home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / share / onboard / sok.py < prev    next >
Encoding:
Python Source  |  2007-02-20  |  15.0 KB  |  518 lines

  1. #!/usr/bin/python
  2.  
  3. from xml.dom import minidom
  4. import gtk
  5. import sys
  6. from Keyboard import Keyboard
  7. from Key import * 
  8. from Pane import Pane
  9. import re
  10. import string
  11.  
  12. from KbdWindow import KbdWindow
  13. import virtkey
  14. import gconf
  15. import gettext
  16.  
  17. from utils import run_script
  18.  
  19. import os.path
  20.  
  21. from utils import *
  22.  
  23. import gettext
  24. from gettext import gettext as _
  25.  
  26. #setup gettext
  27. app="onboard"
  28. gettext.textdomain(app)
  29. gettext.bindtextdomain(app)
  30.  
  31.  
  32. class Sok:
  33.     def __init__(self):
  34.         # This is done so multiple keys with the same modifier don't interfere with each other.
  35.         self.mods = {1:0,2:0, 4:0,8:0, 16:0,32:0,64:0,128:0}
  36.         
  37.         self.SOK_INSTALL_DIR = os.path.dirname(os.path.abspath(__file__))
  38.         sys.path.append("%s/scripts" % self.SOK_INSTALL_DIR)
  39.         
  40.         self.vk = virtkey.virtkey()
  41.          
  42.         self.gconfClient = gconf.client_get_default()
  43.         
  44.         filename = self.gconfClient.get_string("/apps/sok/layout_filename")
  45.         self.window = KbdWindow(self)
  46.         
  47.         if not filename or not os.path.exists(filename):
  48.         self.load_default_layout()
  49.  
  50.         else:
  51.         self.load_layout(filename)
  52.         
  53.         self.window.set_keyboard(self.keyboard)
  54.         
  55.         self.gconfClient.add_dir("/apps/sok",gconf.CLIENT_PRELOAD_NONE)
  56.         
  57.         self.macros = self.gconfClient.get_list("/apps/sok/macros",gconf.VALUE_STRING)
  58.  
  59.         uiManager = gtk.UIManager()
  60.         
  61.         actionGroup = gtk.ActionGroup('UIManagerExample')
  62.         actionGroup.add_actions([('Quit', gtk.STOCK_QUIT, _('_Quit'), None,
  63.                                   _('Quit onBoard'), self.quit),
  64.                                  ('Settings', gtk.STOCK_PREFERENCES, _('_Settings'), None, _('Show settings'), self.cb_settings_item_clicked)])
  65.  
  66.         uiManager.insert_action_group(actionGroup, 0)
  67.  
  68.         uiManager.add_ui_from_string("""<ui>
  69.                         <popup>
  70.                             <menuitem action="Settings"/>
  71.                             <menuitem action="Quit"/>
  72.                         </popup>
  73.                     </ui>""")
  74.         
  75.  
  76.  
  77.         self.trayMenu = uiManager.get_widget("/ui/popup")
  78.  
  79.         
  80.         try:
  81.         self.statusIcon = gtk.status_icon_new_from_file("%s/onboard.svg" % self.SOK_INSTALL_DIR)
  82.             self.statusIcon.connect("activate", self.cb_status_icon_clicked)
  83.             self.statusIcon.connect("popup-menu", self.cb_status_icon_menu)
  84.  
  85.  
  86.             if not self.gconfClient.get_bool("/apps/sok/trayicon"):
  87.             self.hide_status_icon()
  88.             else:
  89.             self.show_status_icon()
  90.         
  91.         except AttributeError:
  92.             print _("You need pygtk 2.10 or above for the system tray icon")
  93.         
  94.  
  95.         self.window.hidden = False
  96.  
  97.         self.window.show_all()
  98.         
  99.  
  100.         self.gconfClient.notify_add("/apps/sok/sizeX",self.window.do_set_size)
  101.             self.gconfClient.notify_add("/apps/sok/layout_filename",self.do_set_layout)
  102.             self.gconfClient.notify_add("/apps/sok/macros",self.do_change_macros)
  103.         self.gconfClient.notify_add("/apps/sok/scanning_interval", self.do_change_scanningInterval)
  104.         self.gconfClient.notify_add("/apps/sok/scanning", self.do_change_scanning)
  105.         self.gconfClient.notify_add("/apps/sok/trayicon", self.do_set_trayicon)
  106.                  
  107.         self.SOK_INSTALL_DIR = os.path.dirname(os.path.abspath(__file__))
  108.         os.chdir(self.SOK_INSTALL_DIR)
  109.         
  110.         scanning = self.gconfClient.get_bool("/apps/sok/scanning")
  111.         if scanning:
  112.             self.scanning = scanning
  113.             self.keyboard.reset_scan()
  114.         else:
  115.             self.scanning = False
  116.         
  117.         scanningInterval = self.gconfClient.get_int("/apps/sok/scanning_interval")
  118.         if scanningInterval:
  119.             self.scanningInterval = scanningInterval
  120.         else:
  121.             self.gconfClient.set_int("/apps/sok/scanning_interval",750)
  122.         
  123.         sys.path.append(os.path.join(self.SOK_INSTALL_DIR,'scripts'))
  124.         
  125.     
  126.     def cb_settings_item_clicked(self,widget):
  127.         run_script("sokSettings",self)
  128.  
  129.     def cb_status_icon_menu(self,status_icon, button, activate_time):
  130.         self.trayMenu.popup(None, None, gtk.status_icon_position_menu, 
  131.              button, activate_time, status_icon)    
  132.  
  133.         
  134.  
  135.  
  136.     def do_set_trayicon(self, cxion_id=None, entry=None, user_data=None,thing=None):
  137.         if self.gconfClient.get_bool("/apps/sok/trayicon"):
  138.             self.show_status_icon()
  139.         else:
  140.             self.hide_status_icon()
  141.         
  142.     
  143.     
  144.     def show_status_icon(self):        
  145.         self.statusIcon.set_visible(True)
  146.         self.window.set_property('skip-taskbar-hint', True)
  147.  
  148.     def hide_status_icon(self):        
  149.         self.statusIcon.set_visible(False)
  150.         self.window.set_property('skip-taskbar-hint', False)
  151.  
  152.     def cb_status_icon_clicked(self,widget):
  153.         if self.window.hidden:
  154.             self.window.show_all()
  155.             self.window.hidden = False            
  156.         else:
  157.             self.window.hide()
  158.             self.window.hidden = True
  159.             
  160.             
  161.         
  162.  
  163.     def unstick(self):
  164.         for key in self.keyboard.basePane.keys.values():
  165.             if key.on :
  166.                 self.keyboard.release_key(key)
  167.             
  168.         
  169.     def clean(self): #Called when sok is gotten rid off.
  170.         self.unstick()
  171.         self.window.hide()
  172.         
  173.     def quit(self, widget=None):
  174.         self.clean()
  175.         gtk.main_quit()
  176.             
  177.     def do_change_scanning(self, cxion_id, entry, user_data,thing):
  178.         self.scanning = self.gconfClient.get_bool("/apps/sok/scanning")
  179.         self.keyboard.reset_scan()
  180.     
  181.     def do_change_scanningInterval(self, cxion_id, entry, user_data,thing):
  182.         self.scanningInterval = self.gconfClient.get_int("/apps/sok/scanningInterval")
  183.     
  184.     def do_change_macros(self,client, cxion_id,entry,user_data):
  185.             self.macros = self.gconfClient.get_list("/apps/sok/macros",gconf.VALUE_STRING)
  186.           
  187.  
  188.     def do_set_layout(self,client, cxion_id, entry, user_data):
  189.         self.unstick()
  190.         filename = self.gconfClient.get_string("/apps/sok/layout_filename")
  191.         if os.path.exists(filename):
  192.             self.load_layout(filename)
  193.             self.window.set_keyboard(self.keyboard)
  194.         else:
  195.             self.load_default_layout()
  196.  
  197.         self.window.set_keyboard(self.keyboard)
  198.     
  199.     def hexstring_to_float(self,hexString):    
  200.         return float(string.atoi(hexString,16))
  201.  
  202.     
  203.     def get_sections_keys(self,section,keys,pane,xOffset,yOffset):
  204.         "gets keys for a specified sections from the XServer."
  205.         rows = self.vk.layout_get_keys(section)
  206.         
  207.         for row in rows:
  208.             for key in row:
  209.                 shape = key['shape']
  210.                 name = key['name'].strip(chr(0)) #since odd characters after names shorter than 4.
  211.                 
  212.                 if name in modDic:
  213.                     nkey = RectKey(pane,float(shape[0] + xOffset),float(shape[1] + yOffset), float(shape[2]), float(shape[3]),(0.95,0.9,0.85,1))
  214.                     props = modDic[name]
  215.                     
  216.                     actions = ("","","",props[1],"")
  217.                     labels =(props[0],"","","","")
  218.                     sticky = True
  219.                 
  220.                 else:
  221.                     
  222.                     
  223.                     actions = ("",key['keysym'],"","","","")
  224.                     
  225.                     if name in otherDic:
  226.                         
  227.                         nkey = RectKey(pane,float(shape[0] + xOffset),float(shape[1] + yOffset), float(shape[2]), float(shape[3]),(0.85,0.8,0.65,1))
  228.                         labels= (otherDic[name],"","","","")
  229.                     else:
  230.                         nkey = RectKey(pane,float(shape[0]+ xOffset),float(shape[1] + yOffset), float(shape[2]), float(shape[3]),(0.9,0.85,0.7,1))
  231.                         labDic = key['labels']
  232.                         labels = (labDic[0],labDic[2],labDic[1],labDic[3],labDic[4])
  233.                         
  234.                     sticky = False
  235.                     
  236.                     
  237.                 nkey.set_properties(actions, labels, sticky,0,0)
  238.                     
  239.                 keys[name] =  nkey
  240.     
  241.     def load_default_layout(self):
  242.         panes = []
  243.         
  244.         sizeA = self.vk.layout_get_section_size("Alpha")
  245.         sizeK = self.vk.layout_get_section_size("Keypad") 
  246.         sizeE = self.vk.layout_get_section_size("Editing")
  247.         sizeF = (294, 94)
  248.         #Tidy this up
  249.         
  250.         
  251.         listX = [sizeA[0],sizeE[0] + sizeK[0] + 20 + 125 ,sizeF[0]]
  252.         listY = [sizeA[1]+ 1,sizeE[1] + 3, sizeK[1]+3,64 ,sizeF[1]] #alpha,editing,keypad,macros,functions
  253.         listX.sort()
  254.         listY.sort()
  255.         sizeX = listX[len(listX)-1]
  256.         sizeY = listY[len(listY)-1]
  257.             
  258.     
  259.     
  260.         keys = {}
  261.         pane = Pane(self,"Alpha", keys,None, float(sizeX), float(sizeY), [0,0,0,0.3],5)
  262.         panes.append(pane)
  263.         self.get_sections_keys("Alpha", keys,pane,0,0)
  264.             
  265.                 
  266.         keys = {}
  267.         pane = Pane(self,"Editing",keys,None, float(sizeX), float(sizeY), [0.3,0.3,0.7,0.3],5)
  268.         panes.append(pane)    
  269.         self.get_sections_keys("Editing", keys, pane, 0, 2)
  270.         self.get_sections_keys("Keypad", keys, pane, sizeE[0] + 20 , 2)
  271.         
  272.         
  273.         
  274.         for r in range(3):
  275.             for c in range(3):
  276.                 n = c + r*3
  277.                 mkey = RectKey(pane,sizeE[0] +sizeK[0] +45 + c*30, 7 + r*28, 25, 24,(0.5,0.5,0.8,1))
  278.                 mkey.set_properties(("", "", "", "",("%d" %n) ),(_("Snippit\n%d") % (n),"","","",""), False,0,0)
  279.                 keys["m%d" % (n)] = mkey
  280.         
  281.         
  282.         
  283.         
  284.         keys = {}
  285.         pane = Pane(self,"Functions",keys,None, float(sizeX), float(sizeY), [0.6,0.3,0.7,0.3],5)
  286.         panes.append(pane)
  287.         y = 0
  288.         for n in range(len(funcKeys)):
  289.             if n  >=8:
  290.                 y = 27
  291.                 m = n -8
  292.             else :
  293.                 m = n
  294.             
  295.             fkey = RectKey(pane,5 + m*30, 5 + y, 25, 24,(0.5,0.5,0.8,1))
  296.             fkey.set_properties(("", funcKeys[n][1], "", ""),(funcKeys[n][0],"","","",""), False,0,0)
  297.             keys[funcKeys[n][0]] = fkey
  298.         
  299.         settingsKey = RectKey(pane,5, 61, 60.0, 30.0,(0.95,0.5,0.5,1))
  300.         settingsKey.set_properties(("","","","","","sokSettings"), (_("Settings"),"","","",""), False,0,0)
  301.         keys["settings"] = settingsKey
  302.         
  303.         switchingKey = RectKey(pane,70 ,61,60.0,30.0,(0.95,0.5,0.5,1))
  304.         switchingKey.set_properties(("","","","","","switchButtons"), (_("Switch\nButtons"),"","","",""), False,0,0)
  305.         keys["switchButtons"] = switchingKey
  306.         
  307.         
  308.         basePane = panes[0]
  309.         otherPanes = panes[1:]
  310.  
  311.         self.keyboard = Keyboard(self,basePane,otherPanes)
  312.         for pane in panes:
  313.             pane.set_DrawingArea(self.keyboard)        
  314.                 
  315.     
  316.     
  317.     def load_keys(self,doc,keys):
  318.         
  319.             for key in doc.getElementsByTagName("key"):  
  320.                 try:
  321.                     if key.attributes["id"].value in keys:
  322.                         actions = ["","","","","",""]
  323.                         if key.hasAttribute("char"):
  324.                             actions[0] = key.attributes["char"].value
  325.                         elif key.hasAttribute("keysym"):
  326.                             value = key.attributes["keysym"].value
  327.                             if value[1] == "x":#Deals for when keysym is a hex value.
  328.                                 actions[1] = string.atoi(value,16)
  329.                             else:
  330.                                 actions[1] = string.atoi(value,10)
  331.                         elif key.hasAttribute("press"):
  332.                             actions[2] = key.attributes["press"].value
  333.                         elif key.hasAttribute("modifier"):
  334.                             actions[3] = modifiers[key.attributes["modifier"].value]
  335.                         elif key.hasAttribute("macro"):
  336.                             actions[4] = key.attributes["macro"].value
  337.                         elif key.hasAttribute("script"):
  338.                             actions[5] = key.attributes["script"].value
  339.  
  340.                         labels = ["","","","",""]
  341.                         if key.hasAttribute("label"):
  342.                             labels[0] = key.attributes["label"].value
  343.                         if key.hasAttribute("cap_label"):
  344.                             labels[1] = key.attributes["cap_label"].value
  345.                         if key.hasAttribute("shift_label"):
  346.                             labels[2] = key.attributes["shift_label"].value
  347.                         if key.hasAttribute("altgr_label"):
  348.                             labels[3] = key.attributes["altgr_label"].value
  349.                         if key.hasAttribute("altgrNshift_label"):
  350.                             labels[4] = key.attributes["altgrNshift_label"].value    
  351.                     
  352.                         if key.hasAttribute("font_offset_x"):
  353.                             offsetX = float(key.attributes["font_offset_x"].value)
  354.                         else:
  355.                             offsetX = 0
  356.                         
  357.                         if key.hasAttribute("font_offset_y"):
  358.                             offsetY = float(key.attributes["font_offset_y"].value)
  359.                         else:
  360.                             offsetY = 0
  361.                         
  362.                         
  363.                         stickyString = key.attributes["sticky"].value
  364.                         if stickyString == "true":
  365.                             sticky = True
  366.                         else:
  367.                             sticky= False
  368.                         
  369.                         keys[key.attributes["id"].value].set_properties(actions,
  370.                                             labels,
  371.                                             sticky, offsetX, offsetY)
  372.                 except KeyError, (strerror):
  373.                     print "key missing id"
  374.  
  375.     def load_layout(self,kblang):
  376.         
  377.         kbfolder = os.path.dirname(kblang)
  378.  
  379.         f = open(kblang)
  380.         langdoc = minidom.parse(f).documentElement
  381.         f.close()
  382.             
  383.             
  384.         panes = []
  385.         
  386.         for paneXML in langdoc.getElementsByTagName("pane"):
  387.             
  388.             try:
  389.                 path= "%s/%s" % (kbfolder,paneXML.attributes["filename"].value)
  390.                 
  391.                 
  392.                 f = open(path)
  393.                 try:            
  394.                         svgdoc = minidom.parse(f).documentElement
  395.                         
  396.             
  397.                     keys = {}
  398.  
  399.                     try:
  400.                                             viewPortSizeX = float(svgdoc.attributes['width'].value)
  401.                                             viewPortSizeY = float(svgdoc.attributes['height'].value)
  402.                                     except ValueError:
  403.                         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"
  404.  
  405.                     #find background of pane
  406.                     paneBackground = [0.0,0.0,0.0,0.0]
  407.             
  408.                     if paneXML.hasAttribute("backgroundRed"):
  409.                         paneBackground[0] = paneXML.attributes["backgroundRed"].value
  410.                     if paneXML.hasAttribute("backgroundGreen"):
  411.                         paneBackground[1] = paneXML.attributes["backgroundGreen"].value
  412.                     if paneXML.hasAttribute("backgroundBlue"):
  413.                         paneBackground[2] = paneXML.attributes["backgroundBlue"].value
  414.                     if paneXML.hasAttribute("backgroundAlpha"):
  415.                         paneBackground[3] = paneXML.attributes["backgroundAlpha"].value
  416.  
  417.                     
  418.                     
  419.                     #scanning
  420.                     columns = []
  421.                     
  422.                     
  423.                     if paneXML.hasAttribute("font"):
  424.                         fontSize = string.atoi(paneXML.attributes["font"].value)
  425.                     else:
  426.                         fontSize = 25
  427.                     
  428.                     pane = Pane(self,paneXML.attributes["id"].value,keys,columns, viewPortSizeX, viewPortSizeY, paneBackground, fontSize)
  429.  
  430.                     
  431.                     for rect in svgdoc.getElementsByTagName("rect"): 
  432.                         id = rect.attributes["id"].value
  433.                         
  434.                         styleString = rect.attributes["style"].value
  435.                         result = re.search("(fill:#\d?\D?\d?\D?\d?\D?\d?\D?\d?\D?\d?\D?;)", styleString).groups()[0]
  436.                 
  437.                         rgba = [self.hexstring_to_float(result[6:8])/255,
  438.                         self.hexstring_to_float(result[8:10])/255,
  439.                         self.hexstring_to_float(result[10:12])/255,
  440.                         1]#not bothered for now 
  441.  
  442.                         keys[id] = RectKey(pane,float(rect.attributes['x'].value),
  443.                                         float(rect.attributes['y'].value),
  444.                                         float(rect.attributes['width'].value),
  445.                                         float(rect.attributes['height'].value),rgba)
  446.                     
  447.                     
  448.                     
  449.                     for path in svgdoc.getElementsByTagName("path"):
  450.                         id = path.attributes["id"].value
  451.                         styleString = rect.attributes["style"].value
  452.                         result = re.search("(fill:#\d?\D?\d?\D?\d?\D?\d?\D?\d?\D?\d?\D?;)", styleString).groups()[0]
  453.                 
  454.                         rgba = (self.hexstring_to_float(result[6:8])/255,
  455.                         self.hexstring_to_float(result[8:10])/255,
  456.                         self.hexstring_to_float(result[10:12])/255,
  457.                         1)#not bothered for now
  458.  
  459.                         dList = path.attributes["d"].value.split(" ")
  460.                         dList = dList[1:-2] #trim unwanted M, Z
  461.                         coordList = []
  462.                         for d in dList:
  463.                             l = d.split(",")
  464.                             for p in l:
  465.                                 if len(p) == 1:
  466.                                     coordList.append(p)
  467.                                 else:
  468.                                     coordList.append(float(p))
  469.  
  470.                         keys[id] = LineKey(pane,coordList,rgba)
  471.                     
  472.                                             
  473.                     
  474.                     svgdoc.unlink()
  475.                     
  476.                     self.load_keys(langdoc,keys)
  477.                     
  478.                     try:
  479.                         
  480.                         for columnXML in paneXML.getElementsByTagName("column"):
  481.                             column = []
  482.                             columns.append(column)
  483.                             for scanKey in columnXML.getElementsByTagName("scankey"):
  484.                                 column.append(keys[scanKey.attributes["id"].value])
  485.                     except KeyError, (strerror):
  486.                         print "require %s key, appears in scanning only" % (strerror)
  487.                     
  488.  
  489.                     panes.append(pane)
  490.                 except KeyError, (strerror):
  491.                     print _("require %s") % (strerror)
  492.                     
  493.                 f.close()
  494.             except KeyError:
  495.                 print _("require filename in pane")
  496.         
  497.         langdoc.unlink()
  498.         
  499.         
  500.         basePane = panes[0]
  501.         otherPanes = panes[1:]
  502.  
  503.         self.keyboard = Keyboard(self,basePane,otherPanes)
  504.         for pane in panes:
  505.             pane.set_DrawingArea(self.keyboard)
  506.  
  507.         
  508.  
  509.             
  510.  
  511.  
  512.  
  513.     
  514. if __name__=='__main__':
  515.     s = Sok()
  516.     gtk.main()
  517.     s.clean()
  518.