On Wed, May 19, 2010 at 03:10:52PM +0200, Tomeu Vizoso wrote:
>On Sat, May 15, 2010 at 23:48, Sugar Labs Bugs
><bugtracker-nore...@sugarlabs.org> wrote:
>> #1686: Accessibility - virtual keyboard
>> ------------------------------------------+---------------------------------
>>    Reporter:  earias                     |          Owner:  tomeu
>>        Type:  defect                     |         Status:  new
>>    Priority:  Unspecified by Maintainer  |      Milestone:  Unspecified by 
>> Release Team
>>   Component:  sugar                      |        Version:  Unspecified
>>    Severity:  Unspecified                |       Keywords:  r?
>> Distribution:  Unspecified                |   Status_field:  Unconfirmed
>> ------------------------------------------+---------------------------------
>> Changes (by bernie):
>>
>>  * keywords:  => r?
>>
>>
>> Comment:
>>
>>  Can someone please review this patch?
>
>Any volunteers in the mailing list?

I'll offer a couple of observations. First, though, I'll reproduce the patch
inline so that I can reply inline and so that everyone can take a good look at
it.

Michael

 From 6781e1bec2c387a740aafe0943c0aa9250482e1a Mon Sep 17 00:00:00 2001
From: Esteban <ear...@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/extensions/globalkey/Makefile.am
+++ b/extensions/globalkey/Makefile.am
@@ -3,4 +3,6 @@ sugardir = $(pkgdatadir)/extensions/globalkey
  sugar_PYTHON =                \
        __init__.py     \
        screenshot.py   \
-       viewsource.py
+       viewsource.py   \
+       virtualkeyboard.py
+
diff --git a/extensions/globalkey/virtualkeyboard.py 
b/extensions/globalkey/virtualkeyboard.py
new file mode 100644
index 0000000..9291142
--- /dev/null
+++ b/extensions/globalkey/virtualkeyboard.py
@@ -0,0 +1,12 @@
+import os
+import gtk
+import logging
+
+from jarabe.model import shell
+import jarabe.view.virtualkeyboard
+
+BOUND_KEYS = ['<alt>k']
+
+def handle_key_press(key):
+       logging.debug('load virtual keyboard')
+       jarabe.view.virtualkeyboard.Teclado()
diff --git a/src/jarabe/model/Makefile.am b/src/jarabe/model/Makefile.am
index 18d44da..ae3dce9 100644
--- a/src/jarabe/model/Makefile.am
+++ b/src/jarabe/model/Makefile.am
@@ -14,4 +14,5 @@ sugar_PYTHON =                        \
        shell.py                \
        screen.py               \
          session.py            \
-       sound.py
+       sound.py                \
+       virtualkeyboard.py
diff --git a/src/jarabe/model/virtualkeyboard.py 
b/src/jarabe/model/virtualkeyboard.py
new file mode 100755
index 0000000..6867f10
--- /dev/null
+++ b/src/jarabe/model/virtualkeyboard.py
@@ -0,0 +1,184 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-1 -*-
+# virtualkeyboard
+# Copyright (C) 2009 Plan Ceibal
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Contact information: comuni...@plan.ceibal.edu.uy
+# Plan Ceibal http://www.ceibal.edu.uy
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import sys, os
+import time
+import pango
+import Xlib.display
+import Xlib.X
+import Xlib.XK
+import Xlib.protocol.event
+
+class Teclado:
+    special_X_keysyms = {
+           ' ' : "space",
+           '\t' : "Tab",
+           '\n' : "Return", 
+           '\r' : "BackSpace",
+           '\e' : "Escape",
+           '!' : "exclam",
+           '#' : "numbersign",
+           '%' : "percent",
+           '$' : "dollar",
+           '&' : "ampersand",
+           '"' : "quotedbl",
+           '\'' : "apostrophe",
+           '(' : "parenleft",
+           ')' : "parenright",
+           '*' : "asterisk",
+           '=' : "equal",
+           '+' : "plus",
+           ',' : "comma",
+           '-' : "minus",
+           '.' : "period",
+           '/' : "slash",
+           ':' : "colon",
+           ';' : "semicolon",
+           '<' : "less",
+           '>' : "greater",
+           '?' : "question",
+           '@' : "at",
+           '[' : "bracketleft",
+           ']' : "bracketright",
+           '\\' : "backslash",
+           '^' : "asciicircum",
+           '_' : "underscore",
+           '`' : "grave",
+           '{' : "braceleft",
+           '|' : "bar",
+           '}' : "braceright",
+           '~' : "asciitilde",
+           'ñ' : "ntilde",
+           'Ñ' : "Ntilde"
+    };
+
+    def __init__(self):
+           self.display = Xlib.display.Display()
+           self.window = self.display.get_input_focus()._data["focus"];
+
+    def get_keysym(self, ch) :
+           keysym = Xlib.XK.string_to_keysym(ch)
+           if keysym == 0 :
+
+               keysym = Xlib.XK.string_to_keysym(self.special_X_keysyms[ch])
+           return keysym
+
+    def is_shifted(self, ch) :
+           if ch.isupper() :
+               return True
+           if "/=...@#$%^&()_*{}|:;\">?Ñ".find(ch) >= 0 :
+               return True
+           return False
+
+    def char_to_keycode(self, ch) :
+           keysym = self.get_keysym(ch)
+           keycode = self.display.keysym_to_keycode(keysym)
+           if keycode == 0 :
+               print "Sorry, can't map", ch
+
+           if (self.is_shifted(ch)) :
+               shift_mask = Xlib.X.ShiftMask
+           else :
+               shift_mask = 0
+
+           return keycode, shift_mask
+
+
+    def send_string(self, ch):
+               keycode, shift_mask = self.char_to_keycode(ch)
+               self.escribir(keycode, shift_mask)
+
+    def escribir(self, keycode, shift_mask):
+               event = Xlib.protocol.event.KeyPress(
+                   time = int(time.time()),
+                   root = self.display.screen().root,
+                   window = self.window,
+                   same_screen = 0, child = Xlib.X.NONE,
+                   root_x = 0, root_y = 0, event_x = 0, event_y = 0,
+                   state = shift_mask,
+                   detail = keycode
+                   )
+               self.window.send_event(event, propagate = True)
+               event = Xlib.protocol.event.KeyRelease(
+                   time = int(time.time()),
+                   root = self.display.screen().root,
+                   window = self.window,
+                   same_screen = 0, child = Xlib.X.NONE,
+                   root_x = 0, root_y = 0, event_x = 0, event_y = 0,
+                   state = shift_mask,
+                   detail = keycode
+                   )
+               self.window.send_event(event, propagate = True)
+
+
+    def escribir_txt(self, txt):
+       self.display = Xlib.display.Display()
+       self.window = self.display.get_input_focus()._data["focus"];
+
+       if (txt == "ü"): 
+               self.escribir(34, 1)
+               self.send_string("u")
+       elif (txt == "Ü"): 
+               self.escribir(34, 1)
+               self.send_string("U")
+       elif (txt == "|"): 
+               self.escribir(10, Xlib.X.Mod5Mask)
+       elif (txt == "@"): 
+               self.escribir(11, Xlib.X.Mod5Mask)
+       elif (txt == "#"): 
+               self.escribir(12, Xlib.X.Mod5Mask)
+       elif (txt == "º"): 
+               self.escribir(49, 0)
+       elif (txt == "ª"): 
+               self.escribir(49, 1)
+       elif (txt == "'"): 
+               self.escribir(20, 0)
+       elif (txt == "¿"): 
+               self.escribir(21, 1)
+       elif (txt == "¡"): 
+               self.escribir(21, 0)
+       elif (txt == "'"):
+               self.escribir(34, 0)
+       elif (self.tieneTilde(txt)):            
+               self.escribir(34, 0)
+               self.escribirVocal(txt)
+       else:
+               self.send_string(txt)
+
+       self.display.sync()
+
+    def tieneTilde(self, txt):
+       return "ÁÉÍÓÚáéíóú".find(txt) >= 0
+
+    def escribirVocal(self, txt):
+       if txt=="Á": self.send_string("A")
+       if txt=="É": self.send_string("E")
+       if txt=="Í": self.send_string("I")
+       if txt=="Ó": self.send_string("O")
+       if txt=="Ú": self.send_string("U")
+       if txt=="á": self.send_string("a")
+       if txt=="é": self.send_string("e")
+       if txt=="í": self.send_string("i")
+       if txt=="ó": self.send_string("o")
+       if txt=="ú": self.send_string("u")
diff --git a/src/jarabe/view/Makefile.am b/src/jarabe/view/Makefile.am
index 1abea6d..4dbd815 100644
--- a/src/jarabe/view/Makefile.am
+++ b/src/jarabe/view/Makefile.am
@@ -9,4 +9,5 @@ sugar_PYTHON =                          \
        pulsingicon.py                  \
        service.py                      \
        tabbinghandler.py               \
-       viewsource.py
+       viewsource.py                   \
+       virtualkeyboard.py
diff --git a/src/jarabe/view/virtualkeyboard.py 
b/src/jarabe/view/virtualkeyboard.py
new file mode 100755
index 0000000..e7697cc
--- /dev/null
+++ b/src/jarabe/view/virtualkeyboard.py
@@ -0,0 +1,865 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-1 -*-
+# virtualkeyboard
+# Copyright (C) 2009 Plan Ceibal
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Contact information: comuni...@plan.ceibal.edu.uy
+# Plan Ceibal http://www.ceibal.edu.uy
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import sys, os
+import time
+import pango
+import gconf
+import logging
+import threading
+import gobject
+
+import jarabe.model.virtualkeyboard
+from sugar.graphics.icon import Icon, get_icon_file_name
+
+gobject.threads_init()
+
+velocidades = {'lenta': 3, 'media': 2, 'rapida':1}
+
+class Teclado:
+
+    def delete_event(self, widget, event=None):
+       self.BOTONESxBARRIDOxFILA = False
+       self.BOTONESxBARRIDO = False
+
+       os.environ['virtualkeyboard'] = 'False'
+        logging.debug('close virtual keyboard')
+        return False
+
+    def __init__(self):
+       self.fila_1 = [];
+       self.fila_2 = [];
+       self.fila_3 = [];
+       self.fila_4 = [];
+       self.fila_5 = [];
+       self.fila_6 = [];
+        self.BOTONESxBARRIDO = False;
+        self.BOTONESxBARRIDOxFILA = False;
+        self.MAYUSCULA = True;
+        self.fila_actual = None;
+        self.btn_actual = None;
+        self.fila_actual_nro = -1;
+        self.seg = 2;
+
+       if os.environ.has_key('virtualkeyboard'):
+               self.visible = os.environ['virtualkeyboard']
+               if self.visible == 'True':
+                       return
+               else:
+                       if self.visible == 'False':                     
+                               self.desplegar()
+       else:
+               self.desplegar()   
+
+    def desplegar(self):
+       self._mTeclado=jarabe.model.virtualkeyboard.Teclado()
+
+       self.dialog = gtk.Dialog()
+       self.dialog.set_title("TECLADO VIRTUAL")
+       try:
+               self.dialog.set_icon_from_file(get_icon_file_name('teclado'))
+       except:
+               logging.debug('dont show virtual keyboard icon')
+
+       self.dialog.set_resizable(True)
+       self.dialog.set_accept_focus(False)
+       #gtk.Window.move(self.dialog, 0, 0)
+
+       self.dialog.connect("delete_event", self.delete_event)
+
+       self.vbox_teclado = self.mostrar_teclado()
+
+       self.event_box = gtk.EventBox()
+       self.event_box.add(self.vbox_teclado)
+       self.event_box.set_events(gtk.gdk.BUTTON_PRESS)
+       self.event_box.show()
+
+
+       self.ebc = self.event_box.connect("button_press_event", 
self.mouse_boton)
+
+       self.dialog.vbox.pack_start(self.event_box, False, False, 5)
+
+       self.vbox_teclado.show_all()
+       self.dialog.show()   
+
+       os.environ['virtualkeyboard'] = 'True'
+
+
+    def mostrar_teclado(self):
+       child = gtk.VBox(False, 2)
+
+       self.btn_BACK_SPACE = self.new_button_borrar()
+
+       self.btn_SPACE = self.new_button_espacio()
+
+       self.btn_CAPS_LOCK = self.new_button_mayuscula()
+       self.fila_3.append(self.btn_CAPS_LOCK)
+
+       self.btn_ENTER = self.new_button_enter()
+       self.fila_2.append(self.btn_ENTER)
+
+       self.btn_TAB = self.new_button_tab()
+       self.fila_2.append(self.btn_TAB)
+
+       self.btn_do = self.new_button_escribir("º")
+       self.fila_1.append(self.btn_do)
+
+       self.btn_1 = self.new_button_escribir("1")
+       self.fila_1.append(self.btn_1)
+
+       self.btn_2 = self.new_button_escribir("2")
+       self.fila_1.append(self.btn_2)
+
+       self.btn_3 = self.new_button_escribir("3")
+       self.fila_1.append(self.btn_3)
+
+       self.btn_4 = self.new_button_escribir("4")
+       self.fila_1.append(self.btn_4)
+
+       self.btn_5 = self.new_button_escribir("5")
+       self.fila_1.append(self.btn_5)
+
+       self.btn_6 = self.new_button_escribir("6")
+       self.fila_1.append(self.btn_6)
+
+       self.btn_7 = self.new_button_escribir("7")
+       self.fila_1.append(self.btn_7)
+       
+       self.btn_8 = self.new_button_escribir("8")
+       self.fila_1.append(self.btn_8)
+
+       self.btn_9 = self.new_button_escribir("9")
+       self.fila_1.append(self.btn_9)
+
+       self.btn_0 = self.new_button_escribir("0")
+       self.fila_1.append(self.btn_0)
+
+       self.btn_finPreg = self.new_button_escribir("'")
+       self.fila_1.append(self.btn_finPreg)
+
+       self.btn_inicioPreg = self.new_button_escribir("¡")
+       self.fila_1.append(self.btn_inicioPreg)
+
+       self.btn_Q = self.new_button_escribir("Q")
+       self.fila_2.append(self.btn_Q)
+
+       self.btn_W = self.new_button_escribir("W")
+       self.fila_2.append(self.btn_W)
+
+       self.btn_E = self.new_button_escribir("E")
+       self.fila_2.append(self.btn_E)
+
+       self.btn_R = self.new_button_escribir("R")
+       self.fila_2.append(self.btn_R)
+
+       self.btn_T = self.new_button_escribir("T")
+       self.fila_2.append(self.btn_T)
+
+       self.btn_Y = self.new_button_escribir("Y")
+       self.fila_2.append(self.btn_Y)
+
+       self.btn_U = self.new_button_escribir("U")      
+       self.fila_2.append(self.btn_U)
+
+       self.btn_I = self.new_button_escribir("I")
+       self.fila_2.append(self.btn_I)
+
+       self.btn_O = self.new_button_escribir("O")
+       self.fila_2.append(self.btn_O)
+
+       self.btn_P = self.new_button_escribir("P")
+       self.fila_2.append(self.btn_P)
+
+       self.btn_asterisco = self.new_button_escribir("*")
+       self.fila_2.append(self.btn_asterisco)
+
+       self.btn_cierra_llave = self.new_button_escribir("]")
+
+       self.btn_A = self.new_button_escribir("A")
+       self.fila_3.append(self.btn_A)
+
+       self.btn_S = self.new_button_escribir("S")
+       self.fila_3.append(self.btn_S)
+
+       self.btn_D = self.new_button_escribir("D")
+       self.fila_3.append(self.btn_D)
+
+       self.btn_F = self.new_button_escribir("F")
+       self.fila_3.append(self.btn_F)
+
+       self.btn_G = self.new_button_escribir("G")
+       self.fila_3.append(self.btn_G)
+
+       self.btn_H = self.new_button_escribir("H")
+       self.fila_3.append(self.btn_H)
+
+       self.btn_J = self.new_button_escribir("J")
+       self.fila_3.append(self.btn_J)
+
+       self.btn_K = self.new_button_escribir("K")
+       self.fila_3.append(self.btn_K)
+
+       self.btn_L = self.new_button_escribir("L")
+       self.fila_3.append(self.btn_L)
+
+       self.btn_enie = self.new_button_escribir("Ñ")
+       self.fila_3.append(self.btn_enie)
+
+       self.btn_mas = self.new_button_escribir("+")
+       self.fila_3.append(self.btn_mas)
+
+       self.fila_3.append(self.btn_cierra_llave)
+
+       self.btn_abre_llave = self.new_button_escribir("[")
+       self.fila_2.append(self.btn_abre_llave)
+
+       self.btn_Z = self.new_button_escribir("Z")
+       self.fila_4.append(self.btn_Z)
+
+       self.btn_X = self.new_button_escribir("X")
+       self.fila_4.append(self.btn_X)
+
+       self.btn_C = self.new_button_escribir("C")
+       self.fila_4.append(self.btn_C)
+
+       self.btn_V = self.new_button_escribir("V")
+       self.fila_4.append(self.btn_V)
+
+       self.btn_B = self.new_button_escribir("B")
+       self.fila_4.append(self.btn_B)
+
+       self.btn_N = self.new_button_escribir("N")
+       self.fila_4.append(self.btn_N)
+
+       self.btn_M = self.new_button_escribir("M")
+       self.fila_4.append(self.btn_M)
+
+       self.btn_coma = self.new_button_escribir(",")
+       self.fila_4.append(self.btn_coma)
+
+       self.btn_punto = self.new_button_escribir(".")
+       self.fila_4.append(self.btn_punto)
+
+       self.btn_guion = self.new_button_escribir("-")
+       self.fila_4.append(self.btn_guion)
+
+       self.btn_A_tilde = self.new_button_escribir("Á")
+       self.fila_5.append(self.btn_A_tilde)
+
+       self.btn_E_tilde = self.new_button_escribir("É")
+       self.fila_5.append(self.btn_E_tilde)
+
+       self.btn_I_tilde = self.new_button_escribir("Í")
+       self.fila_5.append(self.btn_I_tilde)
+
+       self.btn_O_tilde = self.new_button_escribir("Ó")
+       self.fila_5.append(self.btn_O_tilde)
+
+       self.btn_U_tilde = self.new_button_escribir("Ú")
+       self.fila_5.append(self.btn_U_tilde)
+
+       self.btn_U_puntos = self.new_button_escribir("Ü")
+       self.fila_5.append(self.btn_U_puntos)
+
+       self.btn_pite = self.new_button_escribir("|")
+       self.fila_5.append(self.btn_pite)
+
+       self.btn_arroba = self.new_button_escribir("@")
+       self.fila_5.append(self.btn_arroba)
+
+       self.btn_menor = self.new_button_escribir("<")
+       self.fila_5.append(self.btn_menor)
+
+       self.chk_activarBarrido_botones = gtk.CheckButton("BOTONES")
+       self.chk_activarBarrido_botones.connect("toggled", 
self.set_botonesXbarridoXfila)
+
+       self.cbo_time_btn = self.combo_tiempos_botones()
+
+       #dibujo tabla
+       table = gtk.Table(7, 15, False)
+
+       table.set_row_spacing(0, 15)
+       table.set_row_spacing(3, 15)
+       table.set_col_spacing(12, 15)   
+       table.set_row_spacing(4, 10)
+
+       table.attach(self.btn_do, 0, 1, 0, 1)
+       table.attach(self.btn_1, 1, 2, 0, 1)
+       table.attach(self.btn_2, 2, 3, 0, 1)
+       table.attach(self.btn_3, 3, 4, 0, 1)
+       table.attach(self.btn_4, 4, 5, 0, 1)
+       table.attach(self.btn_5, 5, 6, 0, 1)
+       table.attach(self.btn_6, 6, 7, 0, 1)
+       table.attach(self.btn_7, 7, 8, 0, 1)
+       table.attach(self.btn_8, 8, 9, 0, 1)
+       table.attach(self.btn_9, 9, 10, 0, 1)
+       table.attach(self.btn_0, 10, 11, 0, 1)
+       table.attach(self.btn_finPreg, 11 ,12, 0, 1)
+       table.attach(self.btn_inicioPreg, 12, 13, 0, 1)
+       table.attach(self.btn_TAB, 0, 1, 1, 2)
+       table.attach(self.btn_Q, 1, 2, 1, 2)
+       table.attach(self.btn_W, 2, 3, 1, 2)
+       table.attach(self.btn_E, 3, 4, 1, 2)
+       table.attach(self.btn_R, 4, 5, 1, 2)
+       table.attach(self.btn_T, 5, 6, 1, 2)
+       table.attach(self.btn_Y, 6, 7, 1, 2)
+       table.attach(self.btn_U, 7, 8, 1, 2)
+       table.attach(self.btn_I, 8, 9, 1, 2)
+       table.attach(self.btn_O, 9, 10, 1, 2)
+       table.attach(self.btn_P, 10, 11, 1, 2)
+       table.attach(self.btn_asterisco, 11, 12, 1, 2)
+       table.attach(self.btn_abre_llave, 12, 13, 1, 2)
+       table.attach(self.btn_A, 1, 2, 2, 3)
+       table.attach(self.btn_S, 2, 3, 2, 3)
+       table.attach(self.btn_D, 3, 4, 2, 3)
+       table.attach(self.btn_F, 4, 5, 2, 3)
+       table.attach(self.btn_G, 5, 6, 2, 3)
+       table.attach(self.btn_H, 6, 7, 2, 3)
+       table.attach(self.btn_J, 7, 8, 2, 3)
+       table.attach(self.btn_K, 8, 9, 2, 3)
+       table.attach(self.btn_L, 9, 10, 2, 3)
+       table.attach(self.btn_enie, 10, 11, 2, 3)
+       table.attach(self.btn_mas, 11, 12, 2, 3)
+       table.attach(self.btn_cierra_llave, 12, 13, 2, 3)
+       table.attach(self.btn_Z, 1, 2, 3, 4)
+       table.attach(self.btn_X, 2, 3, 3, 4)
+       table.attach(self.btn_C, 3, 4, 3, 4)
+       table.attach(self.btn_V, 4, 5, 3, 4)
+       table.attach(self.btn_B, 5, 6, 3, 4)
+       table.attach(self.btn_N, 6, 7, 3, 4)
+       table.attach(self.btn_M, 7, 8, 3, 4)
+       table.attach(self.btn_coma, 8, 9, 3, 4)
+       table.attach(self.btn_punto, 9, 10, 3, 4)
+       table.attach(self.btn_guion, 10, 11, 3, 4)
+
+       table.attach(self.btn_BACK_SPACE, 13, 15, 0, 1)
+       table.attach(self.btn_ENTER, 13, 15, 1, 2)
+       table.attach(self.btn_CAPS_LOCK, 13, 15, 2, 3)
+       table.attach(self.cbo_time_btn, 13, 14, 4, 5)
+       table.attach(self.chk_activarBarrido_botones, 13, 14, 3, 4)
+       table.attach(self.btn_SPACE, 1, 13, 5, 6)
+
+       table.attach(self.btn_A_tilde, 1, 2, 4, 5)
+       table.attach(self.btn_E_tilde, 2, 3, 4, 5)
+       table.attach(self.btn_I_tilde, 3, 4, 4, 5)
+       table.attach(self.btn_O_tilde, 4, 5, 4, 5)
+       table.attach(self.btn_U_tilde, 5, 6, 4, 5)
+       table.attach(self.btn_U_puntos, 8, 9, 4, 5)
+       table.attach(self.btn_pite, 9, 10, 4, 5)
+       table.attach(self.btn_arroba, 10, 11, 4, 5)
+       table.attach(self.btn_menor, 11, 12, 4, 5)
+
+       child.pack_end(table, True, True, 0)      
+
+       return child
+
+####################################################################################
+       
+    def escribir(self, widget, *arg):
+       hbox = widget.get_children()[0]
+       label = hbox.get_children()[0]
+       txt = label.get_text()
+
+       self._mTeclado.escribir_txt(txt)
+
+    def espacio(self, *arg):
+       self._mTeclado.escribir_txt(" ")
+
+    def tab(self, *arg):
+        self._mTeclado.escribir_txt("\t")
+
+    def enter(self, *arg):
+        self._mTeclado.escribir_txt("\n")
+
+    def borrar(self, *arg):
+        self._mTeclado.escribir_txt("\r")
+
+    def new_button_escribir(self, plabel):
+       btn = Boton(plabel)
+       btn.connect("pressed", self.escribir, plabel)
+       btn.connect("activate", self.escribir, plabel)
+       return btn
+
+
+    def new_button_enter(self):
+       btn = Boton("ENTER")
+       btn.connect("pressed", self.enter)
+       btn.connect("activate", self.enter)
+       return btn
+
+    def new_button_espacio(self):
+       btn = Boton("ESPACIO")
+       btn.connect("pressed", self.espacio)
+       btn.connect("activate", self.espacio)
+       return btn
+
+    def new_button_borrar(self):
+       btn = Boton("BORRAR")
+       btn.connect("pressed", self.borrar)
+       btn.connect("activate", self.borrar)
+       return btn
+
+    def new_button_tab(self):
+       btn = Boton("TAB")
+       btn.connect("pressed", self.tab)
+       btn.connect("activate", self.tab)
+       return btn
+
+    def new_button_mayuscula(self):
+       btn = Boton("MINÚSCULAS")
+       btn.connect("pressed", self.set_mayuscula)
+       btn.connect("activate", self.set_mayuscula)
+       return btn
+
+    def set_mayuscula(self, *arg):
+       if (self.MAYUSCULA):
+               self.btn_do.set_text("ª")
+               self.btn_1.set_text("!")
+               self.btn_2.set_text("\"")
+               self.btn_3.set_text("#")
+               self.btn_4.set_text("$")
+               self.btn_5.set_text("%")
+               self.btn_6.set_text("&")
+               self.btn_7.set_text("/")
+               self.btn_8.set_text("(")
+               self.btn_9.set_text(")")
+               self.btn_0.set_text("=")
+               self.btn_finPreg.set_text("?")
+               self.btn_inicioPreg.set_text("¿")
+               self.btn_Q.set_text("q")
+               self.btn_W.set_text("w")
+               self.btn_E.set_text("e")
+               self.btn_R.set_text("r")
+               self.btn_T.set_text("t")
+               self.btn_Y.set_text("y")
+               self.btn_U.set_text("u")
+               self.btn_I.set_text("i")
+               self.btn_O.set_text("o")
+               self.btn_P.set_text("p")
+               self.btn_A.set_text("a")
+               self.btn_S.set_text("s")
+               self.btn_D.set_text("d")
+               self.btn_F.set_text("f")
+               self.btn_G.set_text("g")
+               self.btn_H.set_text("h")
+               self.btn_J.set_text("j")
+               self.btn_K.set_text("k")
+               self.btn_L.set_text("l")
+               self.btn_enie.set_text("ñ")
+               self.btn_menor.set_text(">")
+               self.btn_Z.set_text("z")
+               self.btn_X.set_text("x")
+               self.btn_C.set_text("c")
+               self.btn_V.set_text("v")
+               self.btn_B.set_text("b")
+               self.btn_N.set_text("n")
+               self.btn_M.set_text("m")
+               self.btn_coma.set_text(";")
+               self.btn_punto.set_text(":")
+               self.btn_guion.set_text("_")
+               self.btn_A_tilde.set_text("á")
+               self.btn_E_tilde.set_text("é")
+               self.btn_I_tilde.set_text("í")
+               self.btn_O_tilde.set_text("ó")
+               self.btn_U_tilde.set_text("ú")
+               self.btn_U_puntos.set_text("ü")
+               self.btn_abre_llave.set_text("{")
+               self.btn_cierra_llave.set_text("}")
+
+               self.MAYUSCULA = False
+               self.btn_CAPS_LOCK.set_text("MAYÚSCULAS")
+       else:
+               self.btn_do.set_text("º")
+               self.btn_1.set_text("1")
+               self.btn_2.set_text("2")
+               self.btn_3.set_text("3")
+               self.btn_4.set_text("4")
+               self.btn_5.set_text("5")
+               self.btn_6.set_text("6")
+               self.btn_7.set_text("7")
+               self.btn_8.set_text("8")
+               self.btn_9.set_text("9")
+               self.btn_0.set_text("0")
+               self.btn_finPreg.set_text("'")
+               self.btn_inicioPreg.set_text("¡")
+               self.btn_Q.set_text("Q")
+               self.btn_W.set_text("W")
+               self.btn_E.set_text("E")
+               self.btn_R.set_text("R")
+               self.btn_T.set_text("T")
+               self.btn_Y.set_text("Y")
+               self.btn_U.set_text("U")
+               self.btn_I.set_text("I")
+               self.btn_O.set_text("O")
+               self.btn_P.set_text("P")
+               self.btn_A.set_text("A")
+               self.btn_S.set_text("S")
+               self.btn_D.set_text("D")
+               self.btn_F.set_text("F")
+               self.btn_G.set_text("G")
+               self.btn_H.set_text("H")
+               self.btn_J.set_text("J")
+               self.btn_K.set_text("K")
+               self.btn_L.set_text("L")
+               self.btn_enie.set_text("Ñ")
+               self.btn_menor.set_text("<")
+               self.btn_Z.set_text("Z")
+               self.btn_X.set_text("X")
+               self.btn_C.set_text("C")
+               self.btn_V.set_text("V")
+               self.btn_B.set_text("B")
+               self.btn_N.set_text("N")
+               self.btn_M.set_text("M")
+               self.btn_coma.set_text(",")
+               self.btn_punto.set_text(".")
+               self.btn_guion.set_text("-")
+               self.btn_A_tilde.set_text("Á")
+               self.btn_E_tilde.set_text("É")
+               self.btn_I_tilde.set_text("Í")
+               self.btn_O_tilde.set_text("Ó")
+               self.btn_U_tilde.set_text("Ú")
+               self.btn_U_puntos.set_text("Ü")
+               self.btn_abre_llave.set_text("[")
+               self.btn_cierra_llave.set_text("]")
+
+               self.MAYUSCULA = True
+               self.btn_CAPS_LOCK.set_text("MINÚSCULAS")
+
+
+########################################################################
+
+    def set_botonesXbarridoXfila(self, widget):
+       state = widget.get_active()
+       if state:       
+               self.BOTONESxBARRIDOxFILA = True
+               self.botonesXbarridoXfila()
+       else:
+               if (self.BOTONESxBARRIDOxFILA):
+                       self.iluminarFila(self.fila_actual_nro, "white")
+               self.BOTONESxBARRIDOxFILA = False
+               self.iluminarBoton(self.btn_actual, "white")
+               self.BOTONESxBARRIDO = False
+
+    def botonesXbarridoXfila(self):
+       gobject.timeout_add(self.seg*1000, self.barrerFocusXfila1)
+
+    def barrerFocusXfila1(self, *arg):
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+       self.fila_actual_nro = 1
+       self.fila_actual = self.fila_1
+       self.iluminarBoton(self.btn_actual, "white")
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+       self.iluminarFila(1, "Yellow")
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+       if self.BOTONESxBARRIDOxFILA:
+               gobject.timeout_add(self.seg*1000, self.barrer_el_boton, 
self.btn_BACK_SPACE,1, 2)
+
+    def barrer_el_boton(self, btn , fila_anterior, fila_a_seguir):
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+       self.fila_actual_nro = -1
+       self.fila_actual = None
+       self.btn_actual = btn
+       self.iluminarFila(fila_anterior, "white")
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+       self.iluminarBoton(self.btn_actual, "Yellow")
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+       if self.BOTONESxBARRIDOxFILA:
+               if fila_a_seguir==1:
+                       gobject.timeout_add(self.seg*1000, 
self.barrerFocusXfila1)
+               if fila_a_seguir==2:
+                       gobject.timeout_add(self.seg*1000, 
self.barrerFocusXfila2)
+               if fila_a_seguir==3:
+                       gobject.timeout_add(self.seg*1000, 
self.barrerFocusXfila3)
+               if fila_a_seguir==4:
+                       gobject.timeout_add(self.seg*1000, 
self.barrerFocusXfila4)
+               if fila_a_seguir==5:
+                       gobject.timeout_add(self.seg*1000, 
self.barrerFocusXfila5)              
+
+
+    def barrerFocusXfila2(self, *arg):
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+
+       self.fila_actual_nro = 2
+       self.fila_actual = self.fila_2
+       self.iluminarBoton(self.btn_actual, "white")
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+       self.iluminarFila(2, "Yellow")
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+
+       if self.BOTONESxBARRIDOxFILA:
+               gobject.timeout_add(self.seg*1000, self.barrer_el_boton, 
self.btn_BACK_SPACE, 2, 3)
+
+    def barrerFocusXfila3(self, *arg):
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+       self.fila_actual_nro = 3
+       self.fila_actual = self.fila_3
+       self.iluminarBoton(self.btn_actual, "white")
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+       self.iluminarFila(3, "Yellow")
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+
+       if self.BOTONESxBARRIDOxFILA:
+               gobject.timeout_add(self.seg*1000, self.barrer_el_boton, 
self.btn_BACK_SPACE, 3, 4)
+
+    def barrerFocusXfila4(self, *arg):
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+       self.fila_actual_nro = 4
+       self.fila_actual = self.fila_4
+       self.iluminarBoton(self.btn_actual, "white")
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+       self.iluminarFila(4, "Yellow")
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+       if self.BOTONESxBARRIDOxFILA:
+               gobject.timeout_add(self.seg*1000, self.barrer_el_boton, 
self.btn_BACK_SPACE, 4, 5)
+
+    def barrerFocusXfila5(self, *arg):
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+       self.fila_actual_nro = 5
+       self.fila_actual = self.fila_5
+       self.iluminarBoton(self.btn_actual, "white")
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+       self.iluminarFila(5, "Yellow")
+       if not self.BOTONESxBARRIDOxFILA:
+               return False
+       if self.BOTONESxBARRIDOxFILA:
+               gobject.timeout_add(self.seg*1000, self.barrer_el_boton, 
self.btn_SPACE, 5, 1)
+
+
+########################################################################
+
+    def iluminarFila(self, fila, color):
+       if fila == 1:
+               for f in range(0,len(self.fila_1)):
+                       gobject.idle_add(self.pintarControl,self.fila_1[f], 
color)
+       if fila == 2:
+               for f in range(0,len(self.fila_2)):
+                       gobject.idle_add(self.pintarControl,self.fila_2[f], 
color)
+       if fila == 3:
+               for f in range(0,len(self.fila_3)):
+                       gobject.idle_add(self.pintarControl,self.fila_3[f], 
color)
+       if fila == 4:
+               for f in range(0,len(self.fila_4)):
+                       gobject.idle_add(self.pintarControl,self.fila_4[f], 
color)
+       if fila == 5:
+               for f in range(0,len(self.fila_5)):
+                       gobject.idle_add(self.pintarControl,self.fila_5[f], 
color)
+       if fila == 6:
+               for f in range(0,len(self.fila_6)):
+                       gobject.idle_add(self.pintarControl,self.fila_6[f], 
color)
+
+    def pintarControl(self, w, color):
+       if not w == None:
+               w.modify_bg( gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
+
+    def mouse_boton(self, widget, event):
+       #evita repeticion
+       self.bloquearHandler()
+
+       if self.BOTONESxBARRIDO:
+               self.BOTONESxBARRIDO=False
+               self.btn_actual.emit("pressed")
+               #voler a empezar...
+               self.iluminarBoton(self.btn_actual, "white")
+               self.BOTONESxBARRIDOxFILA = True
+               self.botonesXbarridoXfila()
+               return
+       if self.BOTONESxBARRIDOxFILA:
+               if self.fila_actual_nro==-1: #es un boton                       
+                       self.btn_actual.emit("pressed")
+               else:
+                       self.BOTONESxBARRIDOxFILA = False;
+                       self.iluminarFila(self.fila_actual_nro, "white")
+                       self.BOTONESxBARRIDO = True;
+                       self.botonesXbarridoEnFila()
+
+    def iluminarBoton(self, btn, color):
+       gobject.idle_add(self.pintarControl,btn, color)
+
+    def bloquearHandler(self):
+       HILO_A = threading.Thread(target = self.bloquearHandler_aux_obj)
+       HILO_A.start()
+       HILO_A.quit = True
+
+    def bloquearHandler_aux_obj(self):
+       self.event_box.handler_block(self.ebc)
+       try:
+               seg=self.get_time_barrido_botones()
+       except:
+               seg = velocidades['media']      
+       if seg == velocidades['rapida']:
+               time.sleep(seg-0.15)
+       if seg == velocidades['media']:
+               time.sleep(seg-0.30)
+       if seg == velocidades['lenta']:
+               time.sleep(seg-0.75)
+       self.event_box.handler_unblock(self.ebc)
+
+
+    def botonesXbarridoEnFila(self):   
+       gobject.idle_add(self.barrerEnFila)
+
+    def barrerEnFila(self):
+       if self.BOTONESxBARRIDO:        
+               i=0
+               gobject.timeout_add(self.seg*1000, self.barrerEnFila_aux, i)
+
+
+    def barrerEnFila_aux(self, i):
+       if not self.BOTONESxBARRIDO:
+               return False
+       try:
+               self.btn_ant = self.fila_actual[i-1]
+       except:
+               return False
+       try:
+               self.btn_actual = self.fila_actual[i]
+       except:
+               self.BOTONESxBARRIDO = False
+               self.BOTONESxBARRIDOxFILA = True
+               self.botonesXbarridoXfila()
+               return False
+       if not self.BOTONESxBARRIDO:
+               return False
+       self.iluminarBoton(self.btn_ant, "white")
+       if not self.BOTONESxBARRIDO:
+               return False
+       self.iluminarBoton(self.btn_actual, "Yellow")
+       if not self.BOTONESxBARRIDO:
+               return False
+       else:
+               gobject.timeout_add(self.seg*1000, self.barrerEnFila_aux, i+1)
+
+    def combo_tiempos_botones(self):
+       cb = gtk.combo_box_new_text()
+       cb.connect("changed", self.on_changed_cbo_time_btn)
+       cb.append_text("RÁPIDO")
+       cb.append_text("MEDIO")
+       cb.append_text("LENTO")
+       seg = velocidades['media']
+       try:
+               seg = self.get_time_barrido_botones()                           
                                        
+       except:
+               seg=velocidades['media']
+
+       if seg==velocidades['rapida']:
+               cb.set_active(0)
+       if seg==velocidades['media']:
+               cb.set_active(1)                
+       if seg==velocidades['lenta']:
+               cb.set_active(2)
+                       
+       return cb
+
+
+    def on_changed_cbo_time_btn(self, widget):
+       s = widget.get_active()
+
+       if s==0:
+               seg = velocidades['rapida']
+       if s==1:
+               seg = velocidades['media']
+       if s==2:
+               seg = velocidades['lenta']
+       
+       self.set_time_barrido_botones(seg)
+       self.seg=seg
+
+
+    def get_time_barrido_botones(self):
+           client = gconf.client_get_default()
+           return client.get_int("/desktop/sugar/virtualkeyboard/time")
+
+    def set_time_barrido_botones(self, seg):
+           client = gconf.client_get_default()
+           client.set_int("/desktop/sugar/virtualkeyboard/time", seg)
+
+class Boton(gtk.Button):
+       font_desc = ''
+       font_color = ''
+       fondo_color = ''
+       text = ''
+
+       def __init__(self, nom=None):
+               gtk.Button.__init__(self)
+
+               self.hbox = gtk.HBox(False, 0)
+               self.add(self.hbox)
+               self.label = gtk.Label(nom)
+
+               self.set_text(nom)
+               self.set_font_desc('sans bold 13')
+               self.set_font_color('black')
+               self.set_fondo_color('white')
+
+               self.label.set_use_underline(True)
+               self.hbox.add(self.label)
+
+       def set_font_desc(self, pfont_desc):
+               self.font_desc = pfont_desc
+               self.label.modify_font(pango.FontDescription(pfont_desc))
+
+       def set_font_color(self, pfont_color):
+               self.font_color = pfont_color
+               self.label.modify_fg(gtk.STATE_NORMAL, 
gtk.gdk.color_parse(pfont_color))
+
+       def set_fondo_color(self, pfondo_color):
+               self.fondo_color = pfondo_color
+               self.modify_bg( gtk.STATE_NORMAL, 
gtk.gdk.color_parse(pfondo_color))
+
+       def set_text(self, ptext):
+               if not ptext == None:
+                       self.text = ptext
+               self.label.set_text(self.text)
+
+       def get_font_desc(self):
+               return self.font_desc
+
+       def get_font_color(self):
+               return self.font_color
+
+       def get_fondo_color(self):
+               return self.fondo_color
+
+       def get_text(self):
+               return self.text
+
+       def is_visible(self):
+               self.get_property('visible')
-- 
1.6.2.5

_______________________________________________
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel

Reply via email to