home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / pyshared / Onboard / OnboardGtk.py < prev    next >
Encoding:
Python Source  |  2008-03-03  |  24.6 KB  |  652 lines

  1. # -*- coding: UTF-8 -*-
  2.  
  3. from xml.dom import minidom
  4. import sys
  5. import gobject
  6. gobject.threads_init()
  7.  
  8. import gtk
  9. import re
  10. import string
  11. import virtkey
  12. import gconf
  13. import gettext
  14. import os.path
  15. import gettext
  16.  
  17. from gettext import gettext as _
  18.  
  19. from Onboard.Keyboard import Keyboard
  20. from KeyGtk import * 
  21. from Onboard.Pane import Pane
  22. from Onboard.KbdWindow import KbdWindow
  23. from optparse import OptionParser
  24.  
  25. import KeyCommon
  26.  
  27. # can't we just import Onboard.utils and then use Onboard.utils.run_script ?
  28. from Onboard.utils import run_script
  29.  
  30. import Onboard.utils as utils
  31.  
  32.  
  33. #setup gettext
  34. app="onboard"
  35. gettext.textdomain(app)
  36. gettext.bindtextdomain(app)
  37.  
  38. DEFAULT_FONTSIZE = 10
  39.  
  40. class OnboardGtk(object):
  41.     """
  42.     This class is a mishmash of things that I didn't have time to refactor in to seperate classes.
  43.     It needs a lot of work.
  44.     The name comes from onboards original working name of simple onscreen keyboard.  
  45.     """
  46.     def __init__(self, main=True):
  47.         
  48.         parser = OptionParser()
  49.         parser.add_option("-l", "--layout", dest="filename",help="Specify layout .sok file")
  50.         parser.add_option("-x", dest="x",help="x coord of window")
  51.         parser.add_option("-y", dest="y",help="y coord of window")
  52.  
  53.         parser.add_option("-s", "--size",dest="size",help="size widthxheight")
  54.  
  55.         (options,args) = parser.parse_args()            
  56.  
  57.         self.SOK_INSTALL_DIR = utils.get_install_dir()       
  58.         if not self.SOK_INSTALL_DIR:
  59.             print "Onboard not installed properly"
  60.             return
  61.  
  62.         sys.path.append(os.path.join(self.SOK_INSTALL_DIR,'scripts'))
  63.         
  64.  
  65.         # this object is the source of all layout info and where we send key presses to be emulated.
  66.         self.vk = virtkey.virtkey()
  67.  
  68.         self.gconfClient = gconf.client_get_default()
  69.         # Get the location of the current layout .sok file from gconf.
  70.         self.gconfClient.add_dir("/apps/sok",gconf.CLIENT_PRELOAD_NONE)
  71.  
  72.         if options.filename:
  73.             filename = options.filename
  74.         else:
  75.             filename = self.gconfClient.get_string("/apps/sok/layout_filename")
  76.  
  77.         if not filename:
  78.             filename = os.path.join(self.SOK_INSTALL_DIR, 
  79.                                                     "layouts", "Default.sok")
  80.  
  81.         if not os.path.exists(filename):
  82.             self.load_default_layout()
  83.         else:
  84.             self.load_layout(filename)
  85.         
  86.         # populates list of macros or "snippets" from gconf
  87.         self.macros = self.gconfClient.get_list("/apps/sok/macros",gconf.VALUE_STRING)
  88.         
  89.         self.window = KbdWindow(self)
  90.         self.window.set_keyboard(self.keyboard)
  91.  
  92.         x = -1
  93.         y = -1
  94.  
  95.         if (options.x):
  96.             x = int(options.x)
  97.  
  98.         if (options.y):
  99.             y = int(options.y)
  100.  
  101.         self.window.move(x, y)
  102.         
  103.  
  104.         if (options.size):
  105.             size = options.size.split("x")
  106.             self.window.set_default_size(int(size[0]),int(size[1]))
  107.  
  108.         #Create menu for trayicon
  109.         uiManager = gtk.UIManager()
  110.         
  111.         actionGroup = gtk.ActionGroup('UIManagerExample')
  112.         actionGroup.add_actions([('Quit', gtk.STOCK_QUIT, _('_Quit'), None,
  113.                                   _('Quit onBoard'), self.quit),
  114.                                  ('Settings', gtk.STOCK_PREFERENCES, _('_Settings'), None, _('Show settings'), self.cb_settings_item_clicked)])
  115.  
  116.         uiManager.insert_action_group(actionGroup, 0)
  117.  
  118.         uiManager.add_ui_from_string("""<ui>
  119.                         <popup>
  120.                             <menuitem action="Settings"/>
  121.                             <menuitem action="Quit"/>
  122.                         </popup>
  123.                     </ui>""")
  124.         trayMenu = uiManager.get_widget("/ui/popup")
  125.  
  126.         # Create the trayicon 
  127.         try:
  128.             self.statusIcon = gtk.status_icon_new_from_file(os.path.join(self.SOK_INSTALL_DIR, "data", "onboard.svg"))
  129.             self.statusIcon.connect("activate", self.cb_status_icon_clicked)
  130.             self.statusIcon.connect("popup-menu", self.cb_status_icon_menu, trayMenu)
  131.  
  132.         except AttributeError:
  133.             print _("You need pygtk 2.10 or above for the system tray icon")
  134.         
  135.  
  136.         self.window.hidden = False
  137.  
  138.         self.window.show_all()
  139.         
  140.         # Watch settings for changes
  141.         self.gconfClient.notify_add("/apps/sok/sizeX",self.window.do_set_size)
  142.         self.gconfClient.notify_add("/apps/sok/layout_filename",self.do_set_layout)
  143.         self.gconfClient.notify_add("/apps/sok/macros",self.do_change_macros)
  144.         self.gconfClient.notify_add("/apps/sok/scanning_interval", self.do_change_scanningInterval)
  145.         self.gconfClient.notify_add("/apps/sok/scanning", self.do_change_scanning)
  146.         self.gconfClient.notify_add("/apps/sok/trayicon", self.do_set_trayicon)
  147.                 
  148.         
  149.         if self.gconfClient.get_bool("/apps/sok/trayicon"):
  150.             self.hide_status_icon()
  151.             self.show_status_icon()
  152.         else:
  153.             self.hide_status_icon()
  154.        
  155.         if main:
  156.             # code moved from 'onboard' executable
  157.             gtk.main()
  158.             self.clean()
  159.     
  160.     def cb_settings_item_clicked(self,widget):
  161.         """
  162.         Callback called when setting button clicked in the trayicon menu. 
  163.         """
  164.         run_script("sokSettings",self)
  165.  
  166.     def cb_status_icon_menu(self,status_icon, button, activate_time,trayMenu):
  167.         """
  168.         Callback called when trayicon right clicked.  Produces menu.
  169.         """
  170.         trayMenu.popup(None, None, gtk.status_icon_position_menu, 
  171.              button, activate_time, status_icon)    
  172.  
  173.     def do_set_trayicon(self, cxion_id=None, entry=None, user_data=None,thing=None):
  174.         """
  175.         Callback called when gconf detects that the gconf key specifying 
  176.         whether the trayicon should be shown or not is changed.
  177.         """
  178.         if self.gconfClient.get_bool("/apps/sok/trayicon"):
  179.             self.show_status_icon()
  180.         else:
  181.             self.hide_status_icon()
  182.         
  183.     def show_status_icon(self):     
  184.         """
  185.         Shows the status icon.  When it is shown we set a wm hint so that
  186.         onboard does not appear in the taskbar.
  187.         """
  188.         self.statusIcon.set_visible(True)
  189.         self.window.set_property('skip-taskbar-hint', True)
  190.  
  191.     def hide_status_icon(self):
  192.         """
  193.         The opposite of the above.
  194.         """
  195.         self.statusIcon.set_visible(False)
  196.         self.window.set_property('skip-taskbar-hint', False)
  197.  
  198.     def cb_status_icon_clicked(self,widget):
  199.         """
  200.         Callback called when trayicon clicked.
  201.         Toggles whether onboard window visibile or not.
  202.  
  203.         TODO would be nice if appeared to iconify to taskbar
  204.         """
  205.         if self.window.hidden:
  206.             self.window.deiconify()
  207.             self.window.hidden = False          
  208.         else:
  209.             self.window.iconify()
  210.             self.window.hidden = True
  211.             
  212.             
  213.         
  214.  
  215.     def unstick(self):
  216.         for key in self.keyboard.basePane.keys.values():
  217.             if key.on :
  218.                 self.keyboard.release_key(key)
  219.             
  220.         
  221.     def clean(self): #Called when sok is gotten rid off.
  222.         self.unstick()
  223.         self.window.hide()
  224.         
  225.     def quit(self, widget=None):
  226.         self.clean()
  227.         gtk.main_quit()
  228.             
  229.     def do_change_scanning(self, cxion_id, entry, user_data,thing):
  230.         self.keyboard.scanning = self.gconfClient.get_bool("/apps/sok/scanning")
  231.         self.keyboard.reset_scan()
  232.     
  233.     def do_change_scanningInterval(self, cxion_id, entry, user_data,thing):
  234.         self.keyboard.scanningInterval = self.gconfClient.get_int("/apps/sok/scanningInterval")
  235.     
  236.     def do_change_macros(self,client, cxion_id,entry,user_data):
  237.         self.macros = self.gconfClient.get_list("/apps/sok/macros",gconf.VALUE_STRING)
  238.           
  239.  
  240.     def do_set_layout(self,client, cxion_id, entry, user_data):
  241.         self.unstick()
  242.         filename = self.gconfClient.get_string("/apps/sok/layout_filename")
  243.         if os.path.exists(filename):
  244.             self.load_layout(filename)
  245.             self.window.set_keyboard(self.keyboard)
  246.         else:
  247.             self.load_default_layout()
  248.  
  249.         self.window.set_keyboard(self.keyboard)
  250.     
  251.     def hexstring_to_float(self,hexString): 
  252.         return float(string.atoi(hexString,16))
  253.  
  254.     
  255.     def get_sections_keys(self, section, keys, pane, xOffset, yOffset):
  256.         "gets keys for a specified sections from the XServer."
  257.         
  258.         rows = self.vk.layout_get_keys(section)
  259.         
  260.         for row in rows:
  261.             for key in row:
  262.                 shape = key['shape']
  263.                 name = key['name'].strip(chr(0)) #since odd characters after names shorter than 4.
  264.                 
  265.                 if name in utils.modDic:
  266.                     nkey = RectKey(pane,float(shape[0] + xOffset),float(shape[1] + yOffset), float(shape[2]), float(shape[3]),(0.95,0.9,0.85,1))
  267.                     props = utils.modDic[name]
  268.                     
  269.                     action = props[1]
  270.                     action_type = KeyCommon.MODIFIER_ACTION
  271.  
  272.                     labels = (props[0],"","","","")
  273.                     sticky = True
  274.                 
  275.                 else:            
  276.                     action = key['keycode']
  277.                     action_type = KeyCommon.KEYCODE_ACTION
  278.                     
  279.                     if name in utils.otherDic:
  280.                         
  281.                         nkey = RectKey(pane,float(shape[0] + xOffset),float(shape[1] + yOffset), float(shape[2]), float(shape[3]),(0.85,0.8,0.65,1))
  282.                         labels = (utils.otherDic[name],"","","","")
  283.                     else:
  284.                         nkey = RectKey(pane,float(shape[0]+ xOffset),float(shape[1] + yOffset), float(shape[2]), float(shape[3]),(0.9,0.85,0.7,1))
  285.                         labDic = key['labels']
  286.                         labels = (labDic[0],labDic[2],labDic[1],labDic[3],labDic[4])
  287.                         
  288.                     sticky = False
  289.                     
  290.                     
  291.                 nkey.setProperties(action_type, action, labels, sticky, 0, 0)
  292.                     
  293.                 keys[name] =  nkey
  294.     
  295.     def load_default_layout(self):
  296.         self.keyboard = Keyboard(self)
  297.         panes = []
  298.         
  299.         sizeA = self.vk.layout_get_section_size("Alpha")
  300.         sizeK = self.vk.layout_get_section_size("Keypad") 
  301.         sizeE = self.vk.layout_get_section_size("Editing")
  302.         sizeF = (294, 94)
  303.         #Tidy this up
  304.         
  305.         
  306.         listX = [sizeA[0],sizeE[0] + sizeK[0] + 20 + 125 ,sizeF[0]]
  307.         listY = [sizeA[1]+ 1,sizeE[1] + 3, sizeK[1]+3,64 ,sizeF[1]] #alpha,editing,keypad,macros,functions
  308.         listX.sort()
  309.         listY.sort()
  310.         sizeX = listX[len(listX)-1]
  311.         sizeY = listY[len(listY)-1]
  312.             
  313.     
  314.     
  315.         keys = {}
  316.         pane = Pane(self.keyboard,"Alpha", keys,None, float(sizeX), float(sizeY), [0,0,0,0.3],DEFAULT_FONTSIZE)
  317.         panes.append(pane)
  318.         self.get_sections_keys("Alpha", keys,pane,0,0)
  319.             
  320.                 
  321.         keys = {}
  322.         pane = Pane(self.keyboard,"Editing",keys,None, float(sizeX), float(sizeY), [0.3,0.3,0.7,0.3],DEFAULT_FONTSIZE)
  323.         panes.append(pane)  
  324.         self.get_sections_keys("Editing", keys, pane, 0, 2)
  325.         self.get_sections_keys("Keypad", keys, pane, sizeE[0] + 20 , 2)
  326.         
  327.         for r in range(3):
  328.             for c in range(3):
  329.                 n = c + r*3
  330.                 mkey = RectKey(pane,sizeE[0] +sizeK[0] +45 + c*38, 7 + r*28, 33, 24,(0.5,0.5,0.8,1))
  331.                 mkey.setProperties(KeyCommon.MACRO_ACTION, str(n), 
  332.                                 (_("Snippet\n%d") % (n),"","","",""), False,0,0)
  333.                 keys["m%d" % (n)] = mkey
  334.         
  335.         keys = {}
  336.         pane = Pane(self.keyboard,"Functions",keys,None, float(sizeX), float(sizeY), [0.6,0.3,0.7,0.3],DEFAULT_FONTSIZE)
  337.         panes.append(pane)
  338.         y = 0
  339.         for n in range(len(utils.funcKeys)):
  340.             if n  >=8:
  341.                 y = 27
  342.                 m = n -8
  343.             else :
  344.                 m = n
  345.             
  346.             fkey = RectKey(pane,5 + m*30, 5 + y, 25, 24,(0.5,0.5,0.8,1))
  347.             fkey.setProperties(KeyCommon.KEYSYM_ACTION, utils.funcKeys[n][1], 
  348.                                 (utils.funcKeys[n][0],"","","",""), False,0,0)
  349.             keys[utils.funcKeys[n][0]] = fkey
  350.         
  351.         settingsKey = RectKey(pane,5, 61, 60.0, 30.0,(0.95,0.5,0.5,1))
  352.         settingsKey.setProperties(KeyCommon.SCRIPT_ACTION, "sokSettings", 
  353.                                     (_("Settings"),"","","",""), False, 0, 0)
  354.         keys["settings"] = settingsKey
  355.         
  356.         switchingKey = RectKey(pane,70 ,61,60.0,30.0,(0.95,0.5,0.5,1))
  357.         switchingKey.setProperties(KeyCommon.SCRIPT_ACTION, "switchButtons", 
  358.                                 (_("Switch\nButtons"),"","","",""), False, 0, 0)
  359.         keys["switchButtons"] = switchingKey
  360.         
  361.         
  362.         basePane = panes[0]
  363.         otherPanes = panes[1:]
  364.  
  365.         self.keyboard.set_basePane(basePane)
  366.  
  367.         for pane in otherPanes:
  368.             self.keyboard.add_pane(pane)
  369.                 
  370.     
  371.     
  372.     def load_keys(self,doc,keys):
  373.         
  374.             for key in doc.getElementsByTagName("key"):  
  375.                 try:
  376.                     if key.attributes["id"].value in keys:
  377.                         action = None
  378.                         action_type = None
  379.  
  380.                         if key.hasAttribute("char"):
  381.                             action = key.attributes["char"].value
  382.                             action_type = KeyCommon.CHAR_ACTION
  383.                         elif key.hasAttribute("keysym"):
  384.                             value = key.attributes["keysym"].value
  385.                             action_type = KeyCommon.KEYSYM_ACTION
  386.                             if value[1] == "x":#Deals for when keysym is hex
  387.                                 action = string.atoi(value,16)
  388.                             else:
  389.                                 action = string.atoi(value,10)
  390.                         elif key.hasAttribute("press"):
  391.                             action = key.attributes["char"].value
  392.                             action_type = KeyCommon.CHAR_ACTION
  393.                         elif key.hasAttribute("modifier"):
  394.                             try:
  395.                                 action = utils.modifiers[
  396.                                             key.attributes["modifier"].value]
  397.                                 action_type = KeyCommon.MODIFIER_ACTION
  398.                             except KeyError, (strerror):
  399.                                 print "Can't find modifier " + str(strerror)
  400.                                 
  401.                         elif key.hasAttribute("macro"):
  402.                             action = key.attributes["macro"].value
  403.                             action_type = KeyCommon.MACRO_ACTION
  404.                         elif key.hasAttribute("script"):
  405.                             action = key.attributes["script"].value
  406.                             action_type = KeyCommon.SCRIPT_ACTION
  407.                         elif key.hasAttribute("keycode"):
  408.                             action = string.atoi(
  409.                                                 key.attributes["keycode"].value)
  410.                             action_type = KeyCommon.KEYCODE_ACTION
  411.  
  412.                         labels = ["","","","",""]
  413.                         #if label specified search for modified labels.
  414.                         if key.hasAttribute("label"):
  415.                             labels[0] = key.attributes["label"].value
  416.  
  417.                             if key.hasAttribute("cap_label"):
  418.                                 labels[1] = key.attributes["cap_label"].value
  419.                             if key.hasAttribute("shift_label"):
  420.                                 labels[2] = key.attributes["shift_label"].value
  421.                             if key.hasAttribute("altgr_label"):
  422.                                 labels[3] = key.attributes["altgr_label"].value
  423.                             if key.hasAttribute("altgrNshift_label"):
  424.                                 labels[4] = key.attributes["altgrNshift_label"].value   
  425.                         #Get labels from keyboard.
  426.                         else:
  427.                             if action_type == KeyCommon.KEYCODE_ACTION:
  428.                                 labDic = self.vk.labels_from_keycode(action)
  429.                                 labels = (labDic[0],labDic[2],labDic[1],
  430.                                                             labDic[3],labDic[4])
  431.  
  432.                     
  433.                         if key.hasAttribute("font_offset_x"):
  434.                             offsetX = float(key.attributes["font_offset_x"].value)
  435.                         else:
  436.                             offsetX = 0
  437.                         
  438.                         if key.hasAttribute("font_offset_y"):
  439.                             offsetY = float(key.attributes["font_offset_y"].value)
  440.                         else:
  441.                             offsetY = 0
  442.                         
  443.                         
  444.                         stickyString = key.attributes["sticky"].value
  445.                         if stickyString == "true":
  446.                             sticky = True
  447.                         else:
  448.                             sticky= False
  449.                         
  450.                         keys[key.attributes["id"].value].setProperties(
  451.                                             action_type, action, labels,
  452.                                             sticky, offsetX, offsetY)
  453.                 except KeyError, (strerror):
  454.                     print "key missing id: " + str(strerror)
  455.  
  456.     def parse_path(self, path, pane):
  457.         id = path.attributes["id"].value
  458.         styleString = path.attributes["style"].value
  459.         result = re.search("(fill:#\d?\D?\d?\D?\d?\D?\d?\D?\d?\D?\d?\D?;)", styleString).groups()[0]
  460.  
  461.         rgba = (self.hexstring_to_float(result[6:8])/255,
  462.         self.hexstring_to_float(result[8:10])/255,
  463.         self.hexstring_to_float(result[10:12])/255,
  464.         1)#not bothered for now
  465.  
  466.         dList = path.attributes["d"].value.split(" ")
  467.         dList = dList[1:-2] #trim unwanted M, Z
  468.         coordList = []
  469.  
  470.         transformMatrix = None
  471.         if path.hasAttribute("transform"):
  472.             transform = path.attributes["transform"].value
  473.             if transform.startswith("matrix"):
  474.                 #Convert strings to floats
  475.                 transformCoords = map(float,transform[7:-1].split(","))
  476.  
  477.                 transformMatrix = (
  478.                     (transformCoords[0],transformCoords[2],transformCoords[4]),
  479.                     (transformCoords[1],transformCoords[3],transformCoords[5]),
  480.                     (0, 0, 1))
  481.             elif transform.startswith("translate"):
  482.                 transformCoords = map(float,transform[10:-1].split(","))
  483.  
  484.                 transformMatrix = (
  485.                     (1.0,0.0,transformCoords[0]),
  486.                     (0.0,1.0,transformCoords[1]),
  487.                     (0.0,0.0,1.0)
  488.                 )
  489.             else:
  490.                 print "Warning: Unhandled transform " + transform
  491.  
  492.         xTotal = 0.0
  493.         yTotal = 0.0
  494.         numCoords = 0
  495.         for d in dList:
  496.             l = d.split(",")
  497.             if len(l) == 1:
  498.                 #A letter
  499.                 coordList.append(l)
  500.             else:
  501.                 #A coord
  502.                 numCoords = numCoords +1
  503.  
  504.                 l = map(float,l)
  505.  
  506.                 if transformMatrix:
  507.                     l = utils.matmult(transformMatrix, l+[1])[:-1]
  508.  
  509.                 xTotal = xTotal + l[0]
  510.                 yTotal = yTotal + l[1]
  511.  
  512.                 coordList.append(l[0])
  513.                 coordList.append(l[1])
  514.  
  515.         #Point at which we want the label drawn
  516.         fontCoord = (xTotal/numCoords, yTotal/numCoords)
  517.  
  518.         return LineKey(pane, coordList, fontCoord, rgba)
  519.  
  520.     def load_layout(self,kblang):
  521.         self.keyboard = Keyboard(self) 
  522.  
  523.         scanning = self.gconfClient.get_bool("/apps/sok/scanning")
  524.         if scanning:
  525.             self.keyboard.scanning = scanning
  526.             self.keyboard.reset_scan()
  527.         else:
  528.             self.keyboard.scanning = False
  529.         
  530.         scanningInterval = self.gconfClient.get_int(
  531.                 "/apps/sok/scanning_interval")
  532.         if scanningInterval:
  533.             self.keyboard.scanningInterval = scanningInterval
  534.         else:
  535.             self.gconfClient.set_int("/apps/sok/scanning_interval",750)
  536.         kbfolder = os.path.dirname(kblang)
  537.  
  538.         f = open(kblang)
  539.         langdoc = minidom.parse(f).documentElement
  540.         f.close()
  541.             
  542.             
  543.         panes = []
  544.         
  545.         for paneXML in langdoc.getElementsByTagName("pane"):
  546.             
  547.             try:
  548.                 path= "%s/%s" % (kbfolder,paneXML.attributes["filename"].value)
  549.                 
  550.                 
  551.                 f = open(path)
  552.                 try:            
  553.                     svgdoc = minidom.parse(f).documentElement
  554.                     keys = {}
  555.  
  556.                     try:
  557.                         viewPortSizeX = float(svgdoc.attributes['width'].value)
  558.                         viewPortSizeY = float(svgdoc.attributes['height'].value)
  559.                     except ValueError:
  560.                         print "Units for canvas height and width must be px.  In the svg file this corresponds with having no units after the height and width"
  561.  
  562.                     #find background of pane
  563.                     paneBackground = [0.0,0.0,0.0,0.0]
  564.             
  565.                     if paneXML.hasAttribute("backgroundRed"):
  566.                         paneBackground[0] = paneXML.attributes["backgroundRed"].value
  567.                     if paneXML.hasAttribute("backgroundGreen"):
  568.                         paneBackground[1] = paneXML.attributes["backgroundGreen"].value
  569.                     if paneXML.hasAttribute("backgroundBlue"):
  570.                         paneBackground[2] = paneXML.attributes["backgroundBlue"].value
  571.                     if paneXML.hasAttribute("backgroundAlpha"):
  572.                         paneBackground[3] = paneXML.attributes["backgroundAlpha"].value
  573.  
  574.                     #scanning
  575.                     columns = []
  576.                     
  577.                     
  578.                     if paneXML.hasAttribute("font"):
  579.                         fontSize = string.atoi(paneXML.attributes["font"].value)
  580.                     else:
  581.                         fontSize = DEFAULT_FONTSIZE
  582.                     
  583.                     pane = Pane(self.keyboard,paneXML.attributes["id"].value,keys,columns, viewPortSizeX, viewPortSizeY, paneBackground, fontSize)
  584.  
  585.                     for rect in svgdoc.getElementsByTagName("rect"): 
  586.                         id = rect.attributes["id"].value
  587.                         
  588.                         styleString = rect.attributes["style"].value
  589.                         result = re.search("(fill:#\d?\D?\d?\D?\d?\D?\d?\D?\d?\D?\d?\D?;)", styleString).groups()[0]
  590.                 
  591.                         rgba = [self.hexstring_to_float(result[6:8])/255,
  592.                         self.hexstring_to_float(result[8:10])/255,
  593.                         self.hexstring_to_float(result[10:12])/255,
  594.                         1]#not bothered for now 
  595.  
  596.                         keys[id] = RectKey(pane,
  597.                             float(rect.attributes['x'].value),
  598.                             float(rect.attributes['y'].value),
  599.                             float(rect.attributes['width'].value),
  600.                             float(rect.attributes['height'].value),rgba)
  601.                     
  602.                     for path in svgdoc.getElementsByTagName("path"):
  603.                         id = path.attributes["id"].value
  604.                         keys[id] = self.parse_path(path, pane)
  605.                                             
  606.                     
  607.                     svgdoc.unlink()
  608.                     
  609.                     self.load_keys(langdoc,keys)
  610.                     
  611.                     try:
  612.                         
  613.                         for columnXML in paneXML.getElementsByTagName("column"):
  614.                             column = []
  615.                             columns.append(column)
  616.                             for scanKey in columnXML.getElementsByTagName("scankey"):
  617.                                 column.append(keys[scanKey.attributes["id"].value])
  618.                     except KeyError, (strerror):
  619.                         print "require %s key, appears in scanning only" % (strerror)
  620.                     
  621.  
  622.                     panes.append(pane)
  623.                 except KeyError, (strerror):
  624.                     print _("require %s") % (strerror)
  625.                     
  626.                 f.close()
  627.             except KeyError:
  628.                 print _("require filename in pane")
  629.         
  630.         langdoc.unlink()
  631.         
  632.         
  633.         basePane = panes[0]
  634.         otherPanes = panes[1:]
  635.  
  636.         self.keyboard.set_basePane(basePane)
  637.  
  638.         for pane in otherPanes:
  639.             self.keyboard.add_pane(pane)
  640.  
  641.         
  642.  
  643.             
  644.  
  645.  
  646.  
  647.     
  648. if __name__=='__main__':
  649.     s = Sok()
  650.     gtk.main()
  651.     s.clean()
  652.