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 / settings.py < prev    next >
Encoding:
Python Source  |  2007-02-20  |  10.7 KB  |  375 lines

  1. #!/usr/bin/python
  2. import gtk
  3. import gtk.glade
  4. import gconf
  5. import gobject
  6.  
  7. from virtkey import virtkey
  8.  
  9. from sok import Sok
  10.  
  11. import shutil
  12.  
  13. from utils import *
  14.  
  15. from xml.parsers.expat import ExpatError
  16. import os
  17. import os.path
  18. import gettext
  19.  
  20. #setup gettext
  21. app="onboard-settings"
  22. gettext.textdomain(app)
  23. gettext.bindtextdomain(app)
  24. gtk.glade.textdomain(app)
  25. gtk.glade.bindtextdomain(app)
  26.  
  27. class Settings:
  28.     def __init__(self,mainwin):
  29.  
  30.             
  31.         self.SOK_INSTALL_DIR = os.path.dirname(os.path.abspath(__file__))
  32.             
  33.         self.gladeXML = gtk.glade.XML(os.path.join(self.SOK_INSTALL_DIR,"settings.glade")) 
  34.         self.window = self.gladeXML.get_widget("settingsWindow")
  35.  
  36.         self.gladeXML.signal_autoconnect({"on_layoutView_released" : self.do_change_layout, 
  37.                 "on_addButton_clicked": self.add_sok,
  38.                 "on_removeButton_clicked": self.cb_removeButton_clicked,
  39.                 "on_macroAddButton_clicked": self.add_macro,
  40.                 "on_closeButton_clicked":self.cb_closeButton_clicked,
  41.                 "on_intervalSpin_value_changed" : self.cb_intervalSpin_value_changed,
  42.                 "on_scanningCheck_toggled" : self.cb_scanningCheck_toggled,
  43.                 "on_closeButton_clicked":gtk.main_quit,
  44.                 "on_personaliseButton_clicked": self.cb_on_personaliseButton_clicked,
  45.                 "on_layoutFolderButton_clicked" : self.cb_layoutFolderButton_clicked,
  46.                 "on_icon_toggled" : self.cb_icon_toggled
  47.                 })
  48.         
  49.         self.layoutView = self.gladeXML.get_widget("layoutView")
  50.         self.macroNumberBox = self.gladeXML.get_widget("macroNumberBox")
  51.         self.macroTextBox = self.gladeXML.get_widget("macroTextBox")
  52.         self.macroDeleteBox = self.gladeXML.get_widget("macroDeleteBox")
  53.         
  54.         self.gconfClient = gconf.client_get_default()
  55.         
  56.  
  57.         self.layoutView.append_column(gtk.TreeViewColumn(None, gtk.CellRendererText(), markup = 0))
  58.                 
  59.  
  60.         self.user_layout_root = "%s/.sok/layouts/" % os.path.expanduser("~")
  61.         if not os.path.exists(self.user_layout_root):
  62.             os.makedirs(self.user_layout_root)
  63.         
  64.         
  65.         self.update_layoutList()
  66.         
  67.         self.on_macros_changed()#Populate the macro list
  68.  
  69.         self.gladeXML.get_widget("icon_toggle").set_active(self.gconfClient.get_bool("/apps/sok/trayicon"))
  70.                     
  71.         
  72.         scanEnabled = self.gconfClient.get_bool("/apps/sok/scanning")
  73.         if scanEnabled:
  74.             self.gladeXML.get_widget("scanningCheck").set_active(True)
  75.         
  76.         scanInterval = self.gconfClient.get_int("/apps/sok/scanning_interval")
  77.         if scanInterval:
  78.             self.gladeXML.get_widget("intervalSpin").set_value(float(scanInterval)/1000)
  79.         
  80.         self.window.show()
  81.             
  82.         self.window.set_keep_above(not mainwin)
  83.         
  84.         self.window.connect("destroy", gtk.main_quit)
  85.  
  86.         
  87.         gtk.main()
  88.  
  89.     
  90.     def on_macros_changed(self,client=None, cxion_id=None, entry=None, user_data=None):
  91.         tempMacroList = self.gconfClient.get_list("/apps/sok/macros",gconf.VALUE_STRING)
  92.         self.macroNumbers = []
  93.         
  94.         for child in self.macroNumberBox.get_children():
  95.             if child.__class__ is gtk.Entry:
  96.                 self.macroNumberBox.remove(child)
  97.         
  98.         for child in self.macroTextBox.get_children():
  99.             if child.__class__ is gtk.Entry:
  100.                 self.macroTextBox.remove(child)
  101.         
  102.         for child in self.macroDeleteBox.get_children():
  103.             if child.__class__ is gtk.Button:
  104.                 self.macroDeleteBox.remove(child)
  105.         
  106.         for n in range(len(tempMacroList)):
  107.             macroStr = tempMacroList[n]
  108.             if macroStr:
  109.                 self.macroNumbers.append(n)
  110.                 
  111.                 numberEntry = gtk.Entry()
  112.                 numberEntry.set_text(str(n))
  113.                 numberEntry.connect("activate",self.cb_macro_numberEntry_activate,n)
  114.                 numberEntry.set_size_request(5, 30)
  115.                 self.macroNumberBox.pack_start(numberEntry,False,False,5)
  116.                 numberEntry.show()
  117.  
  118.                 textEntry = gtk.Entry()
  119.                 textEntry.set_text(macroStr)
  120.                 textEntry.connect("activate",self.cb_macro_textEntry_activate,n)
  121.                 textEntry.set_size_request(-1, 30)
  122.                 self.macroTextBox.pack_start(textEntry,False,False,5)
  123.                 textEntry.show()
  124.                 
  125.                 deleteButton = gtk.Button(stock=gtk.STOCK_DELETE)
  126.                 deleteButton.connect("clicked",self.cb_macro_deleteButton_clicked,n)
  127.                 self.macroDeleteBox.pack_start(deleteButton,False,False,5)
  128.                 deleteButton.show()
  129.                 
  130.  
  131.     def cb_macro_numberEntry_activate(self,widget,currentNumber):
  132.         
  133.         newNo = int(widget.get_text())
  134.         
  135.         if not newNo in self.macroNumbers:
  136.             li = self.gconfClient.get_list("/apps/sok/macros",gconf.VALUE_STRING)
  137.             
  138.             if newNo > (len(li) - 1):
  139.                 for n in range(len(li) - (newNo - 1)):        
  140.                     li.append("")
  141.             text = li[currentNumber]
  142.  
  143.             li[currentNumber] = ""
  144.             li[newNo] = text
  145.             
  146.             self.gconfClient.set_list("/apps/sok/macros",gconf.VALUE_STRING,li)
  147.             
  148.             self.on_macros_changed()
  149.         else:
  150.             dialog = gtk.MessageDialog(self.window,type=gtk.MESSAGE_WARNING,buttons=gtk.BUTTONS_OK,message_format="Snippit already assigned to this number")
  151.             dialog.run()
  152.             widget.set_text(str(currentNumber))
  153.             dialog.destroy()
  154.             
  155.             
  156.  
  157.     def cb_macro_textEntry_activate(self,widget,currentNumber):
  158.         li = self.gconfClient.get_list("/apps/sok/macros",gconf.VALUE_STRING)        
  159.         
  160.         li[currentNumber] = widget.get_text()
  161.         
  162.         self.gconfClient.set_list("/apps/sok/macros",gconf.VALUE_STRING,li)
  163.         
  164.         self.on_macros_changed()
  165.         
  166.         
  167.         
  168.  
  169.     def cb_macro_deleteButton_clicked(self,widget,currentNumber):
  170.         li = self.gconfClient.get_list("/apps/sok/macros",gconf.VALUE_STRING)        
  171.         
  172.         li[currentNumber] = ""
  173.         
  174.         self.gconfClient.set_list("/apps/sok/macros",gconf.VALUE_STRING,li)
  175.         
  176.         self.on_macros_changed()
  177.  
  178.     def cb_icon_toggled(self,widget):
  179.         self.gconfClient.set_bool("/apps/sok/trayicon",widget.get_active())
  180.  
  181.     def open_user_layout_dir(self):
  182.         if os.path.exists('/usr/bin/nautilus'):
  183.             os.system(("nautilus --no-desktop %s" %self.user_layout_root))
  184.         elif os.path.exists('/usr/bin/thunar'):
  185.             os.system(("thunar %s" %self.user_layout_root))
  186.         else:
  187.             print "No file manager to open layout folder"
  188.             
  189.     def cb_layoutFolderButton_clicked(self,widget):
  190.         self.open_user_layout_dir()
  191.     
  192.     def cb_on_personaliseButton_clicked(self, widget):
  193.         dialog = MacroDialog(self.window, "Enter name for personalised layout") #recycling
  194.         dialog.show_all()
  195.         response = dialog.run()
  196.         if response == gtk.RESPONSE_OK:
  197.             text = dialog.macroEntry.get_text()
  198.             s = Sok()
  199.             create_default_layout_XML(text, virtkey(), s)
  200.             s.clean()
  201.             self.update_layoutList()
  202.             self.open_user_layout_dir()
  203.             
  204.         dialog.destroy()
  205.         
  206.     def cb_scanningCheck_toggled(self,widget):
  207.         self.gconfClient.set_bool("/apps/sok/scanning",widget.get_active())
  208.     
  209.     def cb_intervalSpin_value_changed(self,widget):
  210.         self.gconfClient.set_int("/apps/sok/scanning_interval", int(widget.get_value()*1000))
  211.     
  212.     def cb_closeButton_clicked(self, widget):
  213.         self.window.destroy()
  214.  
  215.     def update_layoutList(self):    
  216.         self.layoutList = gtk.ListStore(str,str)
  217.         self.layoutView.set_model(self.layoutList)
  218.         
  219.         it = self.layoutList.append(("Default", ""))
  220.         self.layoutView.get_selection().select_iter(it)
  221.         self.get_soks(os.path.join(self.SOK_INSTALL_DIR,"layouts"))
  222.         self.get_soks(self.user_layout_root)
  223.         
  224.     
  225.     def cb_selected_layout_changed(self):
  226.         self.get_soks(self.user_layout_root)
  227.  
  228.     def cb_macroList_drag_drop(self, widget, event,thing1,thing2,thing3):
  229.         gobject.idle_add(self.macroList_changed)#To make sure gtk has finished changing the value of macroList before updating gconf.
  230.         
  231.  
  232.     def add_macro(self, event):
  233.  
  234.         dialog = MacroDialog(self.window,"Enter text for snippit")
  235.  
  236.         dialog.show_all()
  237.         response = dialog.run()
  238.         if response == gtk.RESPONSE_OK:
  239.             text = dialog.macroEntry.get_text()
  240.             
  241.             l = self.gconfClient.get_list("/apps/sok/macros",gconf.VALUE_STRING)
  242.             
  243.             if self.macroNumbers:
  244.                 if len(l) <= (self.macroNumbers[-1] +1):
  245.                     l.append(text)
  246.                 else:
  247.                     l[self.macroNumbers[-1] + 1] = text
  248.             else:
  249.                 l.append(text)
  250.             self.gconfClient.set_list("/apps/sok/macros",gconf.VALUE_STRING, l)
  251.             
  252.         dialog.destroy()
  253.         
  254.         self.on_macros_changed()        
  255.         
  256.  
  257.     
  258.     
  259.     def add_sok(self, event):#todo filtering
  260.         chooser = gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_OPEN,
  261.                                       buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
  262.         filterer = gtk.FileFilter()
  263.         filterer.add_pattern("*.sok")
  264.         chooser.add_filter(filterer)
  265.         response = chooser.run()
  266.         if response == gtk.RESPONSE_OK:
  267.             filename = chooser.get_filename()
  268.                 
  269.  
  270.             f = open(filename)
  271.             sokdoc = minidom.parse(f).documentElement
  272.             for p in sokdoc.getElementsByTagName("pane"):
  273.                 fn = p.attributes['filename'].value
  274.                 
  275.                 shutil.copyfile("%s/%s" % (os.path.dirname(filename), fn), "%s%s" % (self.user_layout_root, fn)) 
  276.             
  277.  
  278.             shutil.copyfile(filename,"%s%s" % (self.user_layout_root, os.path.basename(filename)))
  279.  
  280.             self.update_layoutList()
  281.         chooser.destroy()
  282.         
  283.  
  284.     def cb_removeButton_clicked(self, event):
  285.         filename = self.layoutList.get_value(self.layoutView.get_selection().get_selected()[1],1)
  286.  
  287.         f = open(filename)
  288.         sokdoc = minidom.parse(f).documentElement
  289.         f.close()
  290.         
  291.         os.remove(filename)
  292.  
  293.         for p in sokdoc.getElementsByTagName("pane"):
  294.             os.remove("%s/%s" % (os.path.dirname(filename), p.attributes['filename'].value))#todo get sok to deal with not having a layout.
  295.         self.gconfClient.set_string("/apps/sok/layout_filename", '')
  296.         self.update_layoutList()
  297.         
  298.  
  299.  
  300.     def get_soks(self, path):
  301.         
  302.         
  303.         
  304.         files = os.listdir(path)
  305.             
  306.         
  307.         soks = []
  308.         for f in files:
  309.             if f[-4:] == ".sok":
  310.                 filename = "%s/%s" % (path,f)
  311.                 theActualFile = open(filename)
  312.                 try:
  313.                     sokdoc = minidom.parse(theActualFile).documentElement
  314.                     if os.access(filename,os.W_OK):
  315.                         it = self.layoutList.append(("<i>%s</i>" % sokdoc.attributes["id"].value,filename))#arg is a tuple. Looks wrong.  Silly python.
  316.                     else:
  317.                         it = self.layoutList.append((sokdoc.attributes["id"].value,filename))
  318.                 
  319.                     if filename == self.gconfClient.get_string("/apps/sok/layout_filename"):
  320.                         self.layoutView.get_selection().select_iter(it)
  321.                 except ExpatError,(strerror):
  322.                     print "XML in %s %s" % (filename, strerror)
  323.                 except KeyError,(strerror):
  324.                     print "key %s required in %s" % (strerror,filename)
  325.                 
  326.                 theActualFile.close()
  327.                 
  328.  
  329.             
  330.  
  331.  
  332.  
  333.     def find_soks(self, path):
  334.         #files = os.listdir("%s/.sok/layouts" % os.path.expanduser("~"))
  335.         files = os.listdir(path)
  336.         soks = []
  337.         for f in files:
  338.             if f[-4:] == ".sok":
  339.                 soks.append(f)
  340.         return soks
  341.  
  342.  
  343.  
  344.     def do_change_layout(self,widget,event):
  345.         
  346.         
  347.         filename = self.layoutList.get_value(widget.get_selection().get_selected()[1],1)
  348.         
  349.         
  350.         
  351.         self.gconfClient.set_string("/apps/sok/layout_filename", filename)
  352.     
  353.     
  354.  
  355.     
  356. class MacroDialog(gtk.MessageDialog):
  357.     def __init__(self,parent,message):
  358.         gtk.MessageDialog.__init__(self,parent,gtk.MESSAGE_QUESTION)
  359.         self.add_buttons(gtk.STOCK_OK,gtk.RESPONSE_OK,
  360.                     gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
  361.         self.macroEntry = gtk.Entry()
  362.         self.macroEntry.connect("activate", self.cb_macroEntry_activated)
  363.         self.vbox.pack_end(self.macroEntry)
  364.         self.set_markup(message)
  365.  
  366.     def cb_macroEntry_activated(self, event):
  367.         self.response(gtk.RESPONSE_OK)
  368.  
  369.             
  370.     
  371. if __name__=='__main__':
  372.     
  373.     s = Settings(True)
  374. #    gtk.main()
  375.