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 / bin / beryl-settings < prev    next >
Encoding:
Text File  |  2007-03-19  |  59.1 KB  |  1,957 lines

  1. #!/usr/bin/env python
  2.  
  3. # This program is free software; you can redistribute it and/or
  4. # modify it under the terms of the GNU General Public License
  5. # as published by the Free Software Foundation; either version 2
  6. # of the License, or (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program; if not, write to the Free Software
  15. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  16. #
  17. # Authors: Quinn Storm (quinn@beryl-project.org)
  18. # Copyright (C) 2007 Quinn Storm
  19.  
  20.  
  21.  
  22. import berylsettings
  23. import gtk
  24. import gtk.gdk
  25. import gobject
  26. import os
  27. import re
  28. gdk = gtk.gdk
  29. from xml.sax.saxutils import escape as EscapeMarkup
  30.  
  31. APP = 'beryl-settings'
  32. DIR = 'locale'
  33. import locale
  34. import gettext
  35. locale.setlocale(locale.LC_ALL, '')
  36. gettext.bindtextdomain(APP, DIR)
  37. gettext.textdomain(APP)
  38. _ = gettext.gettext
  39.  
  40.  
  41. DATADIR  = "/usr/share"
  42. IMAGEDIR = "/usr/share/bsm/images"
  43. PREFIX   = "/usr"
  44. VERSION  = "0.2.1"
  45.  
  46. BaseDir = DATADIR+"/bsm/images"
  47. CatImages = {"wm":"window-management.svg",
  48.         "accessibility":"accessibility.svg",
  49.         "desktop":"desktop.svg",
  50.         "effects":"visual-effects.svg",
  51.         "misc":"extras.svg",
  52.         "devel":"development.svg",
  53.         "__general":"general-settings.svg",
  54.         "imageformat":"images.svg"}
  55.  
  56. GenStore = gtk.TreeStore(
  57.         gobject.TYPE_STRING,    #Entry Name
  58.         gobject.TYPE_STRING,    #Key binding
  59.         gobject.TYPE_BOOLEAN,    #key enabled
  60.         gobject.TYPE_STRING,    #Button binding
  61.         gobject.TYPE_BOOLEAN,    #button enabled
  62.         gobject.TYPE_STRING,    #plugin name
  63.         gobject.TYPE_STRING,    #setting name
  64.         )
  65.  
  66. GenStoreFiltered = GenStore.filter_new()
  67.  
  68. EdgeStore = gtk.ListStore(gobject.TYPE_STRING,gobject.TYPE_STRING,gobject.TYPE_STRING,gobject.TYPE_BOOLEAN)
  69. EdgeDesc = [
  70.             [("Top Left Corner","TopLeft"), ("Top Edge","Top"), ("Top Right Corner","TopRight")],
  71.             [("Left Edge","Left"),("..",""),("Right Edge","Right")],
  72.             [("Bottom Left Corner","BottomLeft"), ("Bottom Edge","Bottom"), ("Bottom Right Corner","BottomRight")]
  73.             ]
  74.  
  75. class FooClass:
  76.     def __init__(self):
  77.         pass
  78.  
  79. Ctx = berylsettings.Context()
  80. Ctx.Read()
  81.  
  82. hideshowall = None
  83. AllowUpdate = True
  84. CurProfLab  = None
  85. AllCats     = []
  86. AllSettings = []
  87. EdgeBoxes   = []
  88. tooltips    = gtk.Tooltips()
  89.  
  90.  
  91. def WriteSettings():
  92.     Ctx.Write()
  93.     berylsettings.send_reload()
  94.  
  95. def QuitAll(v):
  96.     gtk.main_quit()
  97.  
  98. def SetPluginsEnabled():
  99.     for Ca in AllCats:
  100.         for Pl in Ca.Plugins:
  101.             if (Pl.Button):
  102.                 Pl.Button.props.active = Pl.Plugin.Enabled
  103.  
  104. def SetWidgetsFromValues():
  105.     global CurProfLab
  106.     global AllowUpdate
  107.     AllowUpdate = False
  108.     if (CurProfLab):
  109.         prof = Ctx.Profile
  110.         if (prof == None):
  111.             prof = _('<Default>')
  112.         prof = EscapeMarkup(prof)
  113.         CurProfLab.set_markup(_("Current Profile: <b>%s</b>")%prof)
  114.     SetPluginsEnabled()
  115.     for set in AllSettings:
  116.         SetWidgetsForSetting(set.Setting)
  117.     AllowUpdate = True
  118.  
  119. def MoveRow(bwid,bothinf):
  120.     dir = bothinf[0]
  121.     inf = bothinf[1]
  122.     sel = inf.TreeView.get_selection().get_selected()
  123.     if (not sel[0]):
  124.         return
  125.     Iter = sel[1]
  126.     Miter = None
  127.     if (dir == 0):
  128.         MIter = inf.ListStore.get_iter_first()
  129.         while(MIter and inf.ListStore.iter_next(MIter)):
  130.             if (inf.ListStore.get_string_from_iter(inf.ListStore.iter_next(MIter)) ==
  131.                     inf.ListStore.get_string_from_iter(Iter)):
  132.                 break
  133.             MIter = inf.ListStore.iter_next(MIter)
  134.         if (not inf.ListStore.iter_next(MIter)):
  135.             MIter = None
  136.     else:
  137.         MIter = inf.ListStore.iter_next(Iter)
  138.     if (MIter):
  139.         istr = inf.ListStore.get_string_from_iter(MIter)
  140.         inf.ListStore.swap(Iter,MIter)
  141.         SetSettingFromWidgets(inf.Setting)
  142.         Iter = inf.ListStore.get_iter_from_string(istr)
  143.         inf.TreeView.get_selection().select_iter(Iter)
  144.  
  145. def AddRow(plb,set):
  146.     inspos = set.TreeView.get_selection().get_selected()[1]
  147.     if (inspos):
  148.         Iter = set.ListStore.insert_after(inspos)
  149.     else:
  150.         Iter = set.ListStore.append()
  151.     set.ListStore.set(Iter,0,_('<New Value>'))
  152.     SetSettingFromWidgets(set)
  153.  
  154. def DelRow(plb,set):
  155.     delpos = set.TreeView.get_selection().get_selected()[1]
  156.     if (not delpos):
  157.         return
  158.     set.ListStore.remove(delpos)
  159.     SetSettingFromWidgets(set)
  160.  
  161. def AddImageFilters(fil):
  162.     for plugin in Ctx.ActivePlugins:
  163.         for feature in Ctx.Plugin(plugin).Provides:
  164.             if (feature.split(':')[0]=='imageext'):
  165.                 fil.add_pattern('*.'+feature.split(':')[1])
  166.             if (feature.split(':')[0]=='imagemime'):
  167.                 fil.add_mime_type(feature.split(':')[1])
  168.  
  169. def UpdatePrev(file_chooser, preview):
  170.     filename = file_chooser.get_preview_filename()
  171.     try:
  172.         pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(filename, 128, 128)
  173.         preview.set_from_pixbuf(pixbuf)
  174.         have_preview = True
  175.     except:
  176.         have_preview = False
  177.     file_chooser.set_preview_widget_active(have_preview)
  178.     return
  179.  
  180. def BrowseDlg(set):
  181.     if (set.Setting.HasHint("directory")):
  182.         action = gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER
  183.     else:
  184.         action = gtk.FILE_CHOOSER_ACTION_OPEN
  185.     dlg = gtk.FileChooserDialog(_("Browse for %s...")%set.Setting.ShortDesc,MainWindow,
  186.             action,(gtk.STOCK_OPEN,gtk.RESPONSE_OK,gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL))
  187.     if (not set.Setting.HasHint("directory")):
  188.         fil = gtk.FileFilter()
  189.         fil.set_name(_("All Files"))
  190.         fil.add_pattern("*")
  191.         dlg.add_filter(fil)
  192.         if (set.Setting.HasHint("image")):
  193.             preview = gtk.Image()
  194.             dlg.set_preview_widget(preview)
  195.             dlg.connect("update-preview",UpdatePrev,preview)
  196.             if (set.Setting.HasHint("pngonly")):
  197.                 fil = gtk.FileFilter()
  198.                 fil.set_name(_("PNG Images"))
  199.                 fil.add_pattern("*.png")
  200.                 fil.add_mime_type(_("image/png"))
  201.                 dlg.add_filter(fil)
  202.                 dlg.set_filter(fil)
  203.             else:
  204.                 fil = gtk.FileFilter()
  205.                 fil.set_name(_("Images"))
  206.                 AddImageFilters(fil)
  207.                 dlg.add_filter(fil)
  208.                 dlg.set_filter(fil)
  209.     ret = dlg.run()
  210.     val = None
  211.     if (ret == gtk.RESPONSE_OK):
  212.         if (dlg.get_filename()):
  213.             val = dlg.get_filename()
  214.     dlg.destroy()
  215.     del dlg
  216.     return val
  217.  
  218. def BrowseEntry(plb,set):
  219.     val = BrowseDlg(set)
  220.     if (val):
  221.         set.Entry.set_text(val)
  222.         SetSettingFromWidgets(set)
  223.  
  224. def BrowseRow(plb,set):
  225.     val = BrowseDlg(set)
  226.     if (val):
  227.         inspos = set.TreeView.get_selection().get_selected()[1]
  228.         if (inspos):
  229.             Iter = set.ListStore.insert_after(inspos)
  230.         else:
  231.             Iter = set.ListStore.append()
  232.         set.ListStore.set(Iter,0,val)
  233.         SetSettingFromWidgets(set)
  234.  
  235. def ChainDisablePlugin(plugin):
  236.     for plg in Ctx.ActivePlugins:
  237.         pp = Ctx.Plugin(plg)
  238.         for pr in plugin.Provides:
  239.             if (pp.Requires.__contains__(pr)):
  240.                 ChainDisablePlugin(pp)
  241.                 break
  242.     plugin.Enabled = False
  243.  
  244. def SatisfyDeps(feature):
  245.     #returns list of plugins that provide feature
  246.     ret = []
  247.     for plugin in Ctx.Plugins:
  248.         if (plugin.Provides.__contains__(feature)):
  249.             ret = ret+[plugin]
  250.     return ret
  251.  
  252. def TryEnablePlugin(plugin):
  253.     #first make sure it doesn't conflict
  254.     for feature in plugin.Provides:
  255.         for p in Ctx.ActivePlugins:
  256.             if (Ctx.Plugin(p).Provides.__contains__(feature)):
  257.                 msg = _("Can't enable plugin <b>%s</b> because it\nprovides feature <i>%s</i> which is also\nprovided by enabled plugin <b>%s</b>.")%(plugin.ShortDesc,feature,Ctx.Plugin(p).ShortDesc)
  258.                 dlg = gtk.Dialog(_("Can't Enable Plugin"),MainWindow,gtk.DIALOG_MODAL,(_("Disable Conflicting Plugin"),gtk.RESPONSE_OK,gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL))
  259.                 hb = gtk.HBox()
  260.                 vb = gtk.VBox()
  261.                 img = gtk.image_new_from_stock(gtk.STOCK_DIALOG_ERROR,gtk.ICON_SIZE_DIALOG)
  262.                 lab = gtk.Label()
  263.                 lab.set_markup(msg)
  264.                 vb.pack_start(img,False,False)
  265.                 hb.pack_start(vb,False,False)
  266.                 hb.pack_start(lab,True,True)
  267.                 dlg.vbox.pack_start(hb,True,True)
  268.                 dlg.vbox.show_all()
  269.                 dlg.set_title(_("Can't Enable Plugin"))
  270.                 ret = dlg.run()
  271.                 dlg.destroy()
  272.                 if (ret == gtk.RESPONSE_CANCEL):
  273.                     return False
  274.                 else:
  275.                     ChainDisablePlugin(Ctx.Plugin(p))
  276.     needs = []
  277.     for req in plugin.Requires:
  278.         noneed = False
  279.         for p in Ctx.ActivePlugins:
  280.             if Ctx.Plugin(p).Provides.__contains__(req):
  281.                 noneed = True
  282.                 break
  283.         if not noneed:
  284.             needs = needs+[req]
  285.     for need in needs:
  286.         dep = SatisfyDeps(need)
  287.         if len(dep) == 0:
  288.             msg = _("Couldn't find any plugins\nthat provide feature <i>%s</i>\nrequired by plugin <b>%s</b>")%(need,plugin.ShortDesc)
  289.             dlg = gtk.MessageDialog(MainWindow,gtk.DIALOG_MODAL,gtk.MESSAGE_ERROR,gtk.BUTTONS_OK)
  290.             dlg.set_markup(msg)
  291.             dlg.set_title(_("Can't Enable Plugin"))
  292.             dlg.run()
  293.             dlg.destroy()
  294.             return False
  295.         dlg = gtk.Dialog(_("Select Plugin to Enable"),MainWindow,gtk.DIALOG_MODAL,(gtk.STOCK_OK,gtk.RESPONSE_OK,gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL))
  296.         icmb = gtk.combo_box_new_text()
  297.         msg = _("The plugin <b>%s</b> requires the feature\n<i>%s</i> which is provided by the following\nplugins.  Please select which to enable.")%(
  298.                 plugin.ShortDesc,need)
  299.         lab = gtk.Label()
  300.         lab.set_markup(msg)
  301.         dlg.vbox.pack_start(lab)
  302.         for p in dep:
  303.             icmb.append_text(p.ShortDesc)
  304.         dlg.vbox.pack_start(icmb,False,False)
  305.         dlg.vbox.show_all()
  306.         icmb.set_active(0)
  307.         ret = dlg.run()
  308.         val = icmb.get_active()
  309.         dlg.destroy()
  310.         if (ret == gtk.RESPONSE_CANCEL):
  311.             return
  312.         if (val == -1):
  313.             return
  314.         if not TryEnablePlugin(dep[val]):
  315.             return False
  316.     plugin.Enabled = True
  317.     return True
  318.  
  319. def PluginButtonClicked(plb,pld):
  320.     global hideshowall
  321.     global AllowUpdate
  322.     if AllowUpdate:
  323.         if (plb.props.active):
  324.             if not TryEnablePlugin(pld.Plugin):
  325.                 AllowUpdate = False
  326.                 SetPluginsEnabled()
  327.                 AllowUpdate = True
  328.                 return
  329.         else:
  330.             ChainDisablePlugin(pld.Plugin)
  331.         AllowUpdate = False
  332.         SetPluginsEnabled()
  333.         UpdateBindingsList(hideshowall.props.active)
  334.         AllowUpdate = True
  335.         WriteSettings()
  336.  
  337. def CatClicked(wid,event,CatInfo):
  338.     for category in AllCats:
  339.         category.Image.set_from_pixbuf(category.BasePixbuf)
  340.         category.Label.set_markup("<small>%s</small>"%(category.Category.ShortDesc))
  341.     CatInfo.Image.set_from_pixbuf(CatInfo.HighPixbuf)
  342.     CatInfo.Label.set_markup("<small><i><b>%s</b></i></small>"%(CatInfo.Category.ShortDesc))
  343.     if (PlugArea.get_child()):
  344.         PlugArea.remove(PlugArea.get_child())
  345.     PlugArea.add(CatInfo.Widget)
  346.     CatInfo.Widget.show_all()
  347.  
  348. def PlugClicked(wid,event,plgInfo):
  349.     pl = AllCats[plgInfo.CatIndex]
  350.     for plugin in pl.Plugins:
  351.         plugin.Image.set_from_pixbuf(plugin.BasePixbuf)
  352.         plugin.Label.set_markup("<small>%s</small>"%(plugin.Plugin.ShortDesc))
  353.     plgInfo.Image.set_from_pixbuf(plgInfo.HighPixbuf)
  354.     plgInfo.Label.set_markup("<small><i><b>%s</b></i></small>"%(plgInfo.Plugin.ShortDesc))
  355.     if (pl.Container.get_child()):
  356.         pl.Container.remove(pl.Container.get_child())
  357.     pl.Container.add(plgInfo.Widget)
  358.     pl.Container.show_all()
  359.  
  360. def TrySetBinding(set,typ,val):
  361.     v0 = set.Value[0]
  362.     v1 = set.Value[1]
  363.     v2 = set.Value[2]
  364.     v3 = set.Value[3]
  365.     if (typ == 0):
  366.         set.Value = [val,v1,v2,v3]
  367.     else:
  368.         set.Value = [v0,val,v2,v3]
  369.     cfl = set.Conflicts(typ)
  370.     if (len(cfl)<1):
  371.         return
  372.     for n in cfl[0][1]:
  373.         if (n.Plugin.Name == '_'):
  374.             continue
  375.         if (n.Plugin.Enabled):
  376.             continue
  377.         cfl[0][1].remove(n)
  378.     for n in cfl[0][1]:
  379.         if (n.Name == set.Name and n.Plugin.Name == set.Plugin.Name):
  380.             cfl[0][1].remove(n)
  381.     if len(cfl[0][1])<1:
  382.         return
  383.     cset = cfl[0][1][0]
  384.     keym = ["keyboard shortcut","mouse shortcut"]
  385.     message = "Cannot set %s\n<b>%s</b> for <b>%s</b> to\n<u>%s</u> because it would conflict with\n%s <b>%s</b>\nfor <b>%s</b>."%(keym[typ],
  386.             set.ShortDesc,set.Plugin.ShortDesc,val.replace('<','<'),keym[typ],cset.ShortDesc,cset.Plugin.ShortDesc)
  387.     dlg = gtk.Dialog(_("Shortcut Conflict"),MainWindow,gtk.DIALOG_MODAL,("Clear Conflicting Binding",gtk.RESPONSE_OK,gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL))
  388.     lab = gtk.Label()
  389.     lab.set_markup(message)
  390.     hbox = gtk.HBox()
  391.     vbox = gtk.VBox()
  392.     hbox.pack_start(vbox,False,False)
  393.     hbox.pack_start(lab,True,True)
  394.     vbox.pack_start(gtk.image_new_from_stock(gtk.STOCK_DIALOG_WARNING,gtk.ICON_SIZE_DIALOG),False,False)
  395.     dlg.vbox.pack_start(hbox,False,False)
  396.     dlg.vbox.show_all()
  397.     ret = dlg.run()
  398.     dlg.destroy()
  399.     if (ret == gtk.RESPONSE_CANCEL):
  400.         set.Value = [v0,v1,v2,v3]
  401.     else:
  402.         v0 = cset.Value[0]
  403.         v1 = cset.Value[1]
  404.         v2 = cset.Value[2]
  405.         v3 = cset.Value[3]
  406.         if (typ == 0):
  407.             v0 = 'Disabled'
  408.         else:
  409.             v1 = 'Disabled'
  410.         cset.Value = [v0,v1,v2,v3]
  411.         #look up cset in the list-store -.-
  412.         Iter = GenStore.get_iter_first()
  413.         while(Iter):
  414.             PIter = GenStore.iter_children(Iter)
  415.             while(PIter):
  416.                 SIter = GenStore.iter_children(PIter)
  417.                 while(SIter):
  418.                     vals = GenStore.get(SIter,5,6)
  419.                     if (vals[0] == cset.Plugin.Name and vals[1] == cset.Name):
  420.                         GenStore.set(SIter,1,cset.Value[0],3,cset.Value[1])
  421.                         return
  422.                     SIter = GenStore.iter_next(SIter)
  423.                 PIter = GenStore.iter_next(PIter)
  424.             Iter = GenStore.iter_next(Iter)
  425.  
  426. def BindChanged(wid,path,tex,valplus):
  427.     val = valplus[0]
  428.     Info = valplus[1]
  429.     global AllowUpdate
  430.     if not AllowUpdate:
  431.         return
  432.     #val is key or button (0,1)
  433.     if Info:
  434.         MyStore = Info.StoreFiltered
  435.     else:
  436.         MyStore = GenStoreFiltered
  437.  
  438.     Iter = MyStore.get_iter_from_string(path)
  439.     if not Iter:
  440.         return
  441.     AllowUpdate = False
  442.     if Info:
  443.         vals = MyStore.get(Iter,5)
  444.         set = Info.Plugin.Setting(vals[0])
  445.     else:
  446.         vals = MyStore.get(Iter,5,6)
  447.         set = Ctx.Plugin(vals[0]).Setting(vals[1])
  448.     TrySetBinding(set,val,tex)
  449.     RIter = MyStore.convert_iter_to_child_iter(Iter)
  450.     if Info:
  451.         MyStore = Info.Store
  452.     else:
  453.         MyStore = GenStore
  454.     if val == 0:
  455.         MyStore.set(RIter,1,set.Value[0])
  456.     else:
  457.         MyStore.set(RIter,3,set.Value[1])
  458.     WriteSettings()
  459.     AllowUpdate = True
  460.  
  461. def SetWidgetsForSetting(setting):
  462.     #find setting in AllSettings
  463.     this = None
  464.     for set in AllSettings:
  465.         if set.Setting.Name == setting.Name and set.Setting.Plugin.Name == setting.Plugin.Name:
  466.             this = set
  467.     if (this == None):
  468.         return
  469.     set = this.Setting
  470.  
  471.     if (setting.Integrated):
  472.         this.Label.set_markup("<span foreground=\"blue\">%s</span>"%(set.ShortDesc))
  473.     else:
  474.         this.Label.set_markup("%s"%(set.ShortDesc))
  475.  
  476.     if (setting.ReadOnly):
  477.         this.ResetButton.set_sensitive(False)
  478.     else:
  479.         this.ResetButton.set_sensitive(True)
  480.  
  481.     if (set.Type == 'Bool'):
  482.         this.Checkbox.props.active = set.Value
  483.         this.Checkbox.set_sensitive(not setting.ReadOnly)
  484.     elif (set.Type == 'Int' or set.Type == 'Float'):
  485.         this.SpinButton.set_value(set.Value)
  486.         this.SpinButton.set_sensitive(not setting.ReadOnly)
  487.     elif (set.Type == 'String' and len(set.Restrictions) == 0):
  488.         this.Entry.set_text(set.Value)
  489.         this.Entry.set_sensitive(not setting.ReadOnly)
  490.     elif (set.Type == 'String'):
  491.         for m in range(0,len(set.Restrictions)):
  492.             if (set.Restrictions[m] == set.Value):
  493.                 this.ComboBox.set_active(m)
  494.                 this.ComboBox.set_sensitive(not setting.ReadOnly)
  495.     elif (set.Type == 'Color'):
  496.         this.ColorButton.set_color(gdk.Color(set.Value[0],set.Value[1],set.Value[2]))
  497.         this.ColorButton.set_alpha(set.Value[3])
  498.         this.ColorButton.set_sensitive(not setting.ReadOnly)
  499.     elif (set.Type == 'Binding' and set.Restrictions[2]):
  500.         this.Checkbox.props.active = set.Value[2]
  501.         this.Checkbox.set_sensitive(not setting.ReadOnly)
  502.     elif (set.Type == 'List of String'):
  503.         if (len(set.Restrictions)):
  504.             for n in this.CheckBoxes:
  505.                 if (set.Value.__contains__(n.String)):
  506.                     n.Checkbox.props.active = True
  507.                 else:
  508.                     n.Checkbox.props.active = False
  509.         else:
  510.             this.ListStore.clear()
  511.             for n in set.Value:
  512.                 Iter = this.ListStore.append()
  513.                 this.ListStore.set(Iter,0,n)
  514.  
  515. def SetSettingFromWidgets(set):
  516.     #set is assumed to be a pair(setting,wid)
  517.     global AllowUpdate
  518.     if (not AllowUpdate):
  519.         return
  520.     setting = set.Setting
  521.     if (setting.Type == 'Bool'):
  522.         setting.Value = set.Checkbox.props.active
  523.     elif (setting.Type == 'Int' or setting.Type == 'Float'):
  524.         setting.Value = set.SpinButton.get_value()
  525.     elif (setting.Type == 'String' and len(setting.Restrictions) == 0):
  526.         setting.Value = set.Entry.get_text()
  527.     elif (setting.Type == 'String'):
  528.         setting.Value = set.ComboBox.get_active_text()
  529.     elif (setting.Type == 'Color'):
  530.         col = set.ColorButton.get_color()
  531.         al = set.ColorButton.get_alpha()
  532.         setting.Value = (col.red,col.green,col.blue,al)
  533.     elif (setting.Type == 'Binding' and setting.Restrictions[2]):
  534.         vv = setting.Value
  535.         setting.Value = [vv[0],vv[1],set.Checkbox.props.active,vv[3]]
  536.     elif (setting.Type == 'List of String'):
  537.         if (len(setting.Restrictions)):
  538.             val = []
  539.             for n in set.CheckBoxes:
  540.                 if (n.Checkbox.props.active):
  541.                     val += [n.String]
  542.             setting.Value = val
  543.         else:
  544.             val = []
  545.             Iter = set.ListStore.get_iter_first()
  546.             while Iter:
  547.                 val += [set.ListStore.get(Iter,0)[0]]
  548.                 Iter = set.ListStore.iter_next(Iter)
  549.             setting.Value = val
  550.     WriteSettings()
  551.     AllowUpdate = False
  552.     SetWidgetsForSetting(setting)
  553.     AllowUpdate = True
  554.  
  555. def SimpleChangedCB(wid,set):
  556.     SetSettingFromWidgets(set)
  557.  
  558. def UpdateBindingsList(ShowHidden):
  559.     global GenStore
  560.     GenStore.clear()
  561.     global EdgeStore
  562.     EdgeStore.clear()
  563.     s = Ctx.Plugins
  564.     for p in range(0,len(s)):
  565.         if (s[p].Name == '_'):
  566.             nn = s[0]
  567.             s[0] = s[p]
  568.             s[p] = nn
  569.     Iter = EdgeStore.append()
  570.     EdgeStore.set(Iter,0,"<small>None</small>",1,"",2,"",3,True)
  571.     if (len(EdgeBoxes) == 3):
  572.         for row in range(0,3):
  573.             for col in range(0,3):
  574.                 if (EdgeBoxes[row][col][0]):
  575.                     EdgeBoxes[row][col][0].set_active_iter(Iter)
  576.     for p in s:
  577.         if (not (ShowHidden or p.Enabled or p.Name == '_')):
  578.             continue
  579.         hasany = False
  580.         for q in p.Settings:
  581.             if q.Type == 'Binding' and q.Restrictions[3]:
  582.                 hasany = True
  583.         if not hasany:
  584.             continue
  585.         Iter = EdgeStore.append()
  586.         EdgeStore.set(Iter,0,"<b>%s</b>"%p.ShortDesc,3,False)
  587.         for q in p.Settings:
  588.             if q.Type == 'Binding' and q.Restrictions[3]:
  589.                 Iter = EdgeStore.append()
  590.                 EdgeStore.set(Iter,0,"<small>%s</small>"%q.ShortDesc,1,p.Name,2,q.Name,3,True)
  591.                 if len(EdgeBoxes) == 3:
  592.                     for row in range(0,3):
  593.                         for col in range(0,3):
  594.                             if (EdgeBoxes[row][col][1] != 0):
  595.                                 set = Ctx.EdgeOwner(EdgeBoxes[row][col][1])
  596.                                 if (set):
  597.                                     if (set.Name == q.Name and set.Plugin.Name == q.Plugin.Name):
  598.                                         EdgeBoxes[row][col][0].set_active_iter(Iter)
  599.  
  600.     for p in range(1,len(s)-1):
  601.         for q in range(p+1,len(s)):
  602.             if (s[p].ShortDesc>s[q].ShortDesc):
  603.                 nn = s[p]
  604.                 s[p] = s[q]
  605.                 s[q] = nn
  606.     for p in s:
  607.         if (not (ShowHidden or p.Enabled or p.Name == '_')):
  608.             continue
  609.         hasany = False
  610.         for m in p.Settings:
  611.             if (m.Type == 'Binding' and (m.Restrictions[0] or m.Restrictions[1])):
  612.                 hasany = True
  613.                 break
  614.         if hasany:
  615.             PIter = GenStore.append(None)
  616.             GenStore.set(PIter,0,p.ShortDesc,1,"",2,False,3,"",4,False,5,"",6,"")
  617.             for g in p.Groups:
  618.                 hasany = False
  619.                 for s in g.SubGroups:
  620.                     for m in s.Settings:
  621.                         if (m.Type == 'Binding' and (m.Restrictions[0] or m.Restrictions[1])):
  622.                             hasany = True
  623.                             break
  624.                     if hasany:
  625.                         break
  626.                 if hasany:
  627.                     GIter = GenStore.append(PIter)
  628.                     GenStore.set(GIter,0,g.Name,1,"",2,False,3,"",4,False,5,"",6,"")
  629.                     for s in g.SubGroups:
  630.                         for m in s.Settings:
  631.                             if (m.Type == 'Binding' and (m.Restrictions[0] or m.Restrictions[1])):
  632.                                 SIter = GenStore.append(GIter)
  633.                                 if (m.Restrictions[0]):
  634.                                     mv0 = m.Value[0]
  635.                                 else:
  636.                                     mv0 = "N/A"
  637.                                 if (m.Restrictions[1]):
  638.                                     mv1 = m.Value[1]
  639.                                 else:
  640.                                     mv1 = "N/A"
  641.                                 if (m.Integrated):
  642.                                     GenStore.set(SIter,0,"<span foreground=\"blue\">%s</span>"%(m.ShortDesc),1,mv0,2,m.Restrictions[0] and not m.ReadOnly,
  643.                                             3,mv1,4,m.Restrictions[1] and not m.ReadOnly,5,p.Name,6,m.Name)
  644.                                 else:
  645.                                     GenStore.set(SIter,0,m.ShortDesc,1,mv0,2,m.Restrictions[0] and not m.ReadOnly,
  646.                                             3,mv1,4,m.Restrictions[1] and not m.ReadOnly,5,p.Name,6,m.Name)
  647.  
  648.  
  649. def HideShowClick(wid):
  650.     UpdateBindingsList(wid.props.active)
  651.  
  652. try:
  653.     statemask = gdk.SHIFT_MASK | gdk.CONTROL_MASK | gdk.MOD1_MASK | gdk.MOD2_MASK | gdk.MOD3_MASK | \
  654.             gdk.MOD5_MASK | gdk.SUPER_MASK | gdk.HYPER_MASK | gdk.META_MASK
  655. except:
  656.     statemask = gdk.SHIFT_MASK | gdk.CONTROL_MASK | gdk.MOD1_MASK | gdk.MOD2_MASK | gdk.MOD3_MASK | \
  657.             gdk.MOD4_MASK | gdk.MOD5_MASK
  658.  
  659. def kpe(win,ev,ent):
  660.     keygot = (ev.keyval,ev.state)
  661.     #check to see if its a modifier key
  662.     #currently this will be a hardcoded list, should perhaps be changed later
  663.     ModKeys = ['Alt_L','Alt_R','AltGr','Super_L','Super_R','Control_L','Control_R','Shift_L','Shift_R','Meta_L','Meta_R','Multi_key']
  664.     if (ModKeys.__contains__(gdk.keyval_name(ev.keyval))):
  665.         return
  666.     ev = gdk.event_get()
  667.     win.grab_remove()
  668.     gdk.keyboard_ungrab()
  669.     win.destroy()
  670.     keygot = (keygot[0],keygot[1]&statemask)
  671.     win.destroy()
  672.     if (keygot[1] == 0 and keygot[0] == gdk.keyval_from_name("Escape")):
  673.         return
  674.     if (keygot[1] == 0 and keygot[0] == gdk.keyval_from_name("BackSpace")):
  675.         ent.set_text("Disabled")
  676.     else:
  677.         ent.set_text(gtk.accelerator_name(keygot[0],keygot[1]))
  678.  
  679.  
  680. def GetKey(wid,ent):
  681.     global keygot
  682.     win = gtk.Window(gtk.WINDOW_POPUP)
  683.     win.set_position(gtk.WIN_POS_MOUSE)
  684.     win.set_resizable(False)
  685.     fram = gtk.Frame()
  686.     win.add(fram)
  687.     fram.set_shadow_type(gtk.SHADOW_OUT)
  688.     align = gtk.Alignment(0,0,0,0)
  689.     align.props.border_width = 32
  690.     str = "Please press the key on the keyboard\n"
  691.     str += "you wish to modify this keyboard-shortcut\n"
  692.     str += "to use from now on. Press BACKSPACE to clear,\n"
  693.     str += "Press ESCAPE to cancel."
  694.     lab = gtk.Label(str)
  695.     fram.add(align)
  696.     align.add(lab)
  697.     win.show_all()
  698.     while(gtk.events_pending()):
  699.         gtk.main_iteration()
  700.     gdk.flush()
  701.     while(gtk.events_pending()):
  702.         gtk.main_iteration()
  703.     win.window.set_events(gdk.KEY_PRESS_MASK)
  704.     gdk.keyboard_grab(win.window,True)
  705.     win.grab_add()
  706.     win.grab_focus()
  707.     keygot = None
  708.     win.connect("key-press-event",kpe,ent)
  709.  
  710. def ClearIt(wid,ent):
  711.     ent.set_text('Disabled')
  712.  
  713. def ResetIt(wid,inf):
  714.     ent = inf[0]
  715.     set = inf[1]
  716.     typ = inf[2]
  717.     vv = set.Value
  718.     v0 = vv[0]
  719.     v1 = vv[1]
  720.     v2 = vv[2]
  721.     v3 = vv[3]
  722.     set.ResetToDefault()
  723.     ent.set_text(set.Value[typ])
  724.     set.Value = [v0,v1,v2,v3]
  725.  
  726. def BindingPopup(wid,path,col,Info):
  727.     global AllowUpdate
  728.     #why does this get a tuple? that makes no sense.
  729.     spath = None
  730.     for foo in path:
  731.         if (spath):
  732.             spath = spath+':'+str(foo)
  733.         else:
  734.             spath = str(foo)
  735.     if (Info):
  736.         MyStore = Info.StoreFiltered
  737.     else:
  738.         MyStore = GenStoreFiltered
  739.     Iter = MyStore.get_iter_from_string(spath)
  740.     if not Iter:
  741.         return
  742.     if (MyStore.iter_has_child(Iter)):
  743.         if (wid.row_expanded(spath)):
  744.             wid.collapse_row(spath)
  745.         else:
  746.             wid.expand_row(spath,False)
  747.         return
  748.     if Info:
  749.         vals = MyStore.get(Iter,5)
  750.         set = Info.Plugin.Setting(vals[0])
  751.     else:
  752.         vals = GenStoreFiltered.get(Iter,5,6)
  753.         set = Ctx.Plugin(vals[0]).Setting(vals[1])
  754.     if (set.ReadOnly):
  755.         return
  756.     dlg = gtk.Dialog("Edit Shortcuts for %s"%set.ShortDesc,MainWindow,gtk.DIALOG_MODAL,(gtk.STOCK_OK,gtk.RESPONSE_OK,gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL))
  757.     vb = dlg.vbox
  758.     tb = gtk.Table()
  759.     tb.props.border_width = 5
  760.     tb.props.row_spacing = 5
  761.     tb.props.column_spacing = 5
  762.     vb.pack_start(tb,False,False)
  763.     kent = None
  764.     bent = None
  765.     if (set.Restrictions[0]):
  766.         lab = gtk.Label(_("Keyboard Binding:"))
  767.         lab.props.xalign = 1
  768.         tb.attach(lab,0,1,0,1)
  769.         ent = gtk.Entry()
  770.         ent.set_text(set.Value[0])
  771.         tb.attach(ent,1,2,0,1)
  772.         grab = gtk.Button(_("Grab Key"))
  773.         tb.attach(grab,2,3,0,1)
  774.         grab.connect("clicked",GetKey,ent)
  775.         clear = gtk.Button("Clear")
  776.         clear.connect("clicked",ClearIt,ent)
  777.         tb.attach(clear,3,4,0,1)
  778.         rest = gtk.Button()
  779.         rest.connect("clicked",ResetIt,(ent,set,0))
  780.         rest.props.image = gtk.image_new_from_stock(gtk.STOCK_CLEAR,gtk.ICON_SIZE_BUTTON)
  781.         tb.attach(rest,4,5,0,1)
  782.         kent = ent
  783.     if (set.Restrictions[1]):
  784.         lab = gtk.Label(_("Mouse Binding:"))
  785.         lab.props.xalign = 1
  786.         tb.attach(lab,0,1,1,2)
  787.         ent = gtk.Entry()
  788.         ent.set_text(set.Value[1])
  789.         tb.attach(ent,1,2,1,2)
  790.         clear = gtk.Button(_("Clear"))
  791.         clear.connect("clicked",ClearIt,ent)
  792.         tb.attach(clear,3,4,1,2)
  793.         rest = gtk.Button()
  794.         rest.connect("clicked",ResetIt,(ent,set,1))
  795.         rest.props.image = gtk.image_new_from_stock(gtk.STOCK_CLEAR,gtk.ICON_SIZE_BUTTON)
  796.         tb.attach(rest,4,5,1,2)
  797.         bent = ent
  798.     lbl_desc = gtk.Label(_(set.LongDesc))
  799.     vb.pack_start(gtk.HSeparator())
  800.     vb.pack_start(lbl_desc,False,False)
  801.     vb.show_all()
  802.     ret = dlg.run()
  803.     if (ret == gtk.RESPONSE_OK):
  804.         if kent:
  805.             TrySetBinding(set,0,kent.get_text())
  806.         if bent:
  807.             # We don't really want a Button1 binding
  808.             if bent.get_text().lower() != "button1":
  809.                 TrySetBinding(set,1,bent.get_text())
  810.         AllowUpdate = False
  811.         RIter = MyStore.convert_iter_to_child_iter(Iter)
  812.         if Info:
  813.             Info.Store.set(RIter,1,set.Value[0],3,set.Value[1])
  814.         else:
  815.             GenStore.set(RIter,1,set.Value[0],3,set.Value[1])
  816.         WriteSettings()
  817.         AllowUpdate = True
  818.     dlg.destroy()
  819.  
  820. def BindingIsVisibleMethod(model,iter,entry):
  821.     if (model.iter_children(iter)):
  822.         niter = model.iter_children(iter)
  823.         while(niter):
  824.             if (BindingIsVisibleMethod(model,niter,entry)):
  825.                 return True
  826.             niter = model.iter_next(niter)
  827.         return False
  828.     text = entry.get_text()
  829.     if len(text) == 0:
  830.         return True
  831.     dat = ' '.join( model.get(iter,0,1,3) )
  832.     for string in text.lower().split(' '):
  833.         if dat.lower().find(string) < 0:
  834.             return False
  835.     return True
  836.  
  837. def UpdateBindingsFilter(foo):
  838.     global AllowUpdate
  839.     if not AllowUpdate:
  840.         return
  841.     AllowUpdate = False
  842.     GenStoreFiltered.refilter()
  843.     AllowUpdate = True
  844.  
  845. def ClearEntry(but,ent):
  846.     ent.set_text('')
  847.  
  848. def MakeBindingsList():
  849.     vbox = gtk.VBox(False,4)
  850.     hbox = gtk.HBox(False,4)
  851.     entry = gtk.Entry()
  852.     clearbut = gtk.Button(gtk.STOCK_CLEAR)
  853.     clearbut.set_use_stock(True)
  854.     hbox.pack_start(gtk.Label(_("Search:")),False,False)
  855.     hbox.pack_start(entry,True,True)
  856.     hbox.pack_start(clearbut,False,False)
  857.     vbox.pack_start(hbox,False,False)
  858.     genview = gtk.TreeView(GenStoreFiltered)
  859.     nameren = gtk.CellRendererText()
  860.     genview.insert_column_with_attributes(0,_("Name"),nameren,markup = 0)
  861.     keyren = gtk.CellRendererText()
  862.     genview.insert_column_with_attributes(1,_("Keyboard"),keyren,text = 1,editable = 2,sensitive = 2)
  863.     butren = gtk.CellRendererText()
  864.     genview.insert_column_with_attributes(2,_("Mouse"),butren,text = 3,editable = 4,sensitive = 4)
  865.     genview.props.headers_visible = True
  866.     genview.props.rules_hint = True
  867.     cont = gtk.ScrolledWindow()
  868.     #cont.props.height_request = 250
  869.     cont.props.hscrollbar_policy = gtk.POLICY_NEVER
  870.     cont.add(genview)
  871.     vwinfr = gtk.Frame()
  872.     vwinfr.props.shadow_type = gtk.SHADOW_IN
  873.     vwinfr.add(cont)
  874.     genview.connect("row-activated",BindingPopup,None)
  875.     keyren.connect("edited",BindChanged,(0,None))
  876.     butren.connect("edited",BindChanged,(1,None))
  877.     entry.connect("changed",UpdateBindingsFilter)
  878.     clearbut.connect("clicked",ClearEntry,entry)
  879.     GenStoreFiltered.set_visible_func(BindingIsVisibleMethod,entry)
  880.     vbox.pack_start(vwinfr,True,True)
  881.     return vbox
  882.  
  883. def EdgeChanged(wid,edg):
  884.     global AllowUpdate
  885.     if not AllowUpdate:
  886.         return
  887.     Iter = wid.get_active_iter()
  888.     if (not Iter):
  889.         return
  890.     vval = wid.get_model().get(Iter,3)
  891.     if not vval:
  892.         return
  893.     oset = Ctx.EdgeOwner(edg)
  894.     if (oset):
  895.         vv = oset.Value
  896.         ne = vv[3]
  897.         if (ne.__contains__(berylsettings.edgetolist(edg)[0])):
  898.             ne.remove(berylsettings.edgetolist(edg)[0])
  899.         oset.Value = [vv[0],vv[1],vv[2],ne]
  900.     vals = wid.get_model().get(Iter,1,2)
  901.     if (vals[0] == '' and vals[1] == ''):
  902.         WriteSettings()
  903.         return
  904.     set = Ctx.Plugin(vals[0]).Setting(vals[1])
  905.     vv = set.Value
  906.     ne = vv[3]
  907.     if not (ne.__contains__(berylsettings.edgetolist(edg)[0])):
  908.         ne = ne+berylsettings.edgetolist(edg)
  909.     set.Value = [vv[0],vv[1],vv[2],ne]
  910.     WriteSettings()
  911.  
  912. def MakeEdgeWidgets():
  913.     global AllowUpdate
  914.     AllowUpdate = False
  915.     global EdgeStore
  916.     tab = gtk.Table()
  917.     al = gtk.VBox()
  918.     al.pack_start(tab,False,False)
  919.     global EdgeBoxes
  920.     EdgeBoxes = []
  921.     for h in range(0,3):
  922.         newbox = []
  923.         for v in range(0,3):
  924.             if (h != 1 or v != 1):
  925.                 align = gtk.Frame(EdgeDesc[v][h][0])
  926.                 box = gtk.ComboBox(EdgeStore)
  927.                 cell = gtk.CellRendererText()
  928.                 cell.props.wrap_width = 140
  929.                 cell.props.wrap_mode = gtk.WRAP_WORD
  930.                 box.pack_start(cell,True)
  931.                 box.add_attribute(cell,'markup',0)
  932.                 box.add_attribute(cell,'sensitive',3)
  933.                 align.add(box)
  934.                 newbox = newbox+[(box,berylsettings.edgelisttomask([EdgeDesc[v][h][1]]))]
  935.                 tab.attach(align,h,h+1,v,v+1)
  936.                 box.connect("changed",EdgeChanged,berylsettings.edgelisttomask([EdgeDesc[v][h][1]]))
  937.             else:
  938.                 newbox = newbox+[(None,0)]
  939.         EdgeBoxes = EdgeBoxes+[newbox]
  940.     UpdateBindingsList(False)
  941.     AllowUpdate = True
  942.     return al
  943.  
  944. def RowEdited(wid,path,tex,set):
  945.     global AllowUpdate
  946.     if not AllowUpdate:
  947.         return
  948.     n = int(path)
  949.     n = set.ListStore.iter_nth_child(None,n)
  950.     set.ListStore.set(n,0,tex)
  951.     SetSettingFromWidgets(set)
  952.     return True
  953.  
  954. def ClearSet(wid,set):
  955.     global AllowUpdate
  956.     if (set.Setting.Type == 'Binding'):
  957.         vv = set.Setting.Value
  958.         v0 = vv[0]
  959.         v1 = vv[1]
  960.         v3 = vv[3]
  961.         set.Setting.ResetToDefault()
  962.         set.Setting.Value = [v0,v1,set.Setting.Value[2],v3]
  963.     else:
  964.         set.Setting.ResetToDefault()
  965.     WriteSettings()
  966.     AllowUpdate = False
  967.     SetWidgetsForSetting(set.Setting)
  968.     AllowUpdate = True
  969.  
  970. def ClearPopupEntry(wid,realwid):
  971.     realwid.set_text("")
  972.  
  973. Row = 0
  974.  
  975. def GetXprop(regexp):
  976.     xprop = os.popen("xprop").readlines()
  977.     rex = re.compile(regexp)
  978.     val = ""
  979.     for line in xprop:
  980.         if rex.search(line):
  981.             m = rex.match(line)
  982.             val = m.group(1).lower().capitalize()
  983.     return val
  984.  
  985. def PutXprop(set,cbox,centry):
  986.     if cbox.get_active_text() == "Window Type":
  987.         val = GetXprop("^_NET_WM_WINDOW_TYPE\(ATOM\) = _NET_WM_WINDOW_TYPE_(\w+)")
  988.     elif cbox.get_active_text() == "Window Class":
  989.         val = GetXprop("^WM_CLASS\(STRING\) = \"([^\"]+)\"")
  990.     elif cbox.get_active_text() == "Window Title":
  991.         val = GetXprop("^WM_NAME\(STRING\) = \"([^\"]+)\"")
  992.     elif cbox.get_active_text() == "Owning Program":
  993.         val = GetXprop("^WM_COMMAND\(STRING\) = \{ \"([^\"]+)\"")
  994.     elif cbox.get_active_text() == "Window Role":
  995.         val = GetXprop("^WM_WINDOW_ROLE\(STRING\) = \"([^\"]+)\"")
  996.     elif cbox.get_active_text() == "Class Name":
  997.         val = GetXprop("^WM_CLASS\(STRING\) = \"[^\"]+\", \"([^\"]+)\"")
  998.     centry.set_text(val)
  999.  
  1000. def StatePopup(button,set):
  1001.     dlg = gtk.Dialog(_("Add criteria for window attribute"),MainWindow,gtk.DIALOG_MODAL,(gtk.STOCK_OK,gtk.RESPONSE_OK,gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL))
  1002.     vbox = dlg.vbox
  1003.     sldr = gtk.HBox(False,8)
  1004.     hbox = gtk.HBox(False,8)
  1005.     vrow = gtk.HBox(False,8)
  1006.     lrow = gtk.HBox(False,8)
  1007.     vbox.pack_start(sldr,True,True)
  1008.     vbox.pack_start(hbox,False,False)
  1009.     vbox.pack_start(vrow,True,True)
  1010.     vbox.pack_start(lrow,True,True)
  1011.     ld = gtk.Label(set.Setting.LongDesc)
  1012.     ld.set_width_chars(50)
  1013.     ld.set_line_wrap(True)
  1014.     sldr.pack_start(ld,True,True)
  1015.     pcombo = gtk.combo_box_new_text()
  1016.     for property in ["Window Type","Window Class","Window Title",\
  1017.             "Owning Program","Class Name","Class Role"]:
  1018.         pcombo.append_text(property)
  1019.     pval = gtk.Entry()
  1020.     pcombo.connect("changed",ClearPopupEntry,pval)
  1021.     pval.width_chars = 15
  1022.     grab = gtk.Button("Grab")
  1023.     grab.connect("clicked",PutXprop,pcombo,pval)
  1024.     if set.Setting.Name in ("opacity","brightness","saturation","opacityabs","brightnessabs","saturationabs"):
  1025.         Adj = gtk.Adjustment(0,0,100,1)
  1026.         bat = gtk.SpinButton(Adj,1,0)
  1027.         valwid = gtk.HScale(Adj)
  1028.         valwid.props.digits = 0
  1029.         vrow.pack_end(bat,True,True)
  1030.     elif set.Setting.Name == "viewport":
  1031.         hsize = Ctx.Plugin("_").Setting("size").Value
  1032.         Adj = gtk.Adjustment(0,0,hsize,1)
  1033.         valwid = gtk.combo_box_new_text()
  1034.         for i in range(hsize):
  1035.             valwid.append_text(str(i))
  1036.     elif set.Setting.Name in ("border","noargb"):
  1037.         valwid = gtk.CheckButton(set.Setting.ShortDesc)
  1038.         valwid.set_active(True)
  1039.     elif set.Setting.Name == "position":
  1040.         valwid = gtk.combo_box_new_text()
  1041.         valwid.append_text(_("Top Left"))
  1042.         valwid.append_text(_("Top Center"))
  1043.         valwid.append_text(_("Top Right"))
  1044.         valwid.append_text(_("Center Left"))
  1045.         valwid.append_text(_("Center"))
  1046.         valwid.append_text(_("Center Right"))
  1047.         valwid.append_text(_("Bottom Left"))
  1048.         valwid.append_text(_("Bottom Center"))
  1049.         valwid.append_text(_("Bottom Right"))
  1050.     lbl = gtk.Label(_("\nSelect the window attribute. Click the Grab button to select a window, then choose a value for the setting."))
  1051.     lbl.set_width_chars(50)
  1052.     lbl.set_line_wrap(True)
  1053.     lrow.pack_start(lbl,True,True)
  1054.     lrow.show_all()
  1055.     sldr.show_all()
  1056.     hbox.pack_start(pcombo,False,False)
  1057.     hbox.pack_start(pval,False,False)
  1058.     hbox.pack_start(grab,False,False)
  1059.     vrow.pack_start(valwid,True,True)
  1060.     hbox.show_all()
  1061.     vrow.show_all()
  1062.     ret = dlg.run()
  1063.     if (ret == gtk.RESPONSE_OK):
  1064.         propname = pcombo.get_active_text()
  1065.         propval  = pval.get_text()
  1066.         if set.Setting.Name == "viewport":
  1067.             val = valwid.get_active_text()
  1068.         elif set.Setting.Name in ("border","noargb"):
  1069.                 if valwid.get_active():
  1070.                     val = "1"
  1071.                 else:
  1072.                     val = "0"
  1073.         elif set.Setting.Name == "position":
  1074.             val = str(valwid.get_active()+1)
  1075.         else:
  1076.             val = str(int(bat.get_value()))
  1077.         if propname != None and propval != None and val != None:
  1078.             AddStateProp(pcombo.get_active_text(),pval.get_text(),val,set)
  1079.     dlg.destroy()
  1080.  
  1081. def AddStateProp(cval,tval,val,set):
  1082.     if cval == "Window Type":
  1083.         let = "w"
  1084.     elif cval == "Window Class":
  1085.         let = "c"
  1086.     elif cval == "Window Title":
  1087.         let = "t"
  1088.     elif cval == "Owning Program":
  1089.         let = "p"
  1090.     elif cval == "Class Name":
  1091.         let = "n"
  1092.     elif cval == "Class Role":
  1093.         let = "r"
  1094.     inspos = set.TreeView.get_selection().get_selected()[1]
  1095.     if (inspos):
  1096.         Iter = set.ListStore.insert_after(inspos)
  1097.     else:
  1098.         Iter = set.ListStore.append()
  1099.     set.ListStore.set(Iter,0,let + ':' + tval + ':' + val)
  1100.     SetSettingFromWidgets(set)
  1101.  
  1102. def MakeAndConnect(wid,setting):
  1103.     global AllSettings
  1104.     global Row
  1105.     resbut = gtk.Button()
  1106.     resbut.props.image = gtk.image_new_from_stock(gtk.STOCK_CLEAR,gtk.ICON_SIZE_BUTTON)
  1107.     SetInfo = FooClass()
  1108.     SetInfo.Setting = setting
  1109.     SetWid = []
  1110.     lab = gtk.Label(setting.ShortDesc)
  1111.     SetInfo.Label = lab
  1112.     SetInfo.ResetButton = resbut
  1113.     if (setting.Type == 'Bool'):
  1114.         foo = gtk.HBox(False,8)
  1115.         foo.pack_start(resbut,False,False)
  1116.         foo.pack_start(lab,False,False)
  1117.         ebox = gtk.EventBox()
  1118.         ebox.add(foo)
  1119.         wid.attach(ebox,0,1,Row,Row+1,gtk.SHRINK)
  1120.         bar = gtk.CheckButton()
  1121.         bar.props.xalign = 0
  1122.         tooltips.set_tip(ebox,setting.LongDesc)
  1123.         tooltips.set_tip(bar,setting.LongDesc)
  1124.         wid.attach(bar,1,2,Row,Row+1)
  1125.         SetInfo.Checkbox = bar
  1126.         bar.connect("toggled",SimpleChangedCB,SetInfo)
  1127.     elif (setting.Type == 'Binding' and setting.Restrictions[2]):
  1128.         foo = gtk.HBox(False,8)
  1129.         foo.pack_start(resbut,False,False)
  1130.         lab.set_text("%s on system bell"%setting.ShortDesc)
  1131.         foo.pack_start(lab,False,False)
  1132.         ebox = gtk.EventBox()
  1133.         ebox.add(foo)
  1134.         wid.attach(ebox,0,1,Row,Row+1,gtk.SHRINK)
  1135.         bar = gtk.CheckButton()
  1136.         bar.props.xalign = 0
  1137.         tooltips.set_tip(bar,setting.LongDesc)
  1138.         tooltips.set_tip(ebox,setting.LongDesc)
  1139.         wid.attach(bar,1,2,Row,Row+1)
  1140.         SetInfo.Checkbox = bar
  1141.         bar.connect("toggled",SimpleChangedCB,SetInfo)
  1142.     elif (setting.Type == 'List of String'):
  1143.         if (len(setting.Restrictions)):
  1144.             foo = gtk.Frame(setting.ShortDesc)
  1145.             bar = gtk.HBox(False,8)
  1146.             bar.props.border_width = 4
  1147.             ebox = gtk.EventBox()
  1148.             ebox.add(bar)
  1149.             tooltips.set_tip(ebox,setting.LongDesc)
  1150.             foo.add(ebox)
  1151.             baz = gtk.VBox(False,0)
  1152.             bar.pack_start(baz,False,False)
  1153.             baz.pack_start(resbut,False,False)
  1154.             checkies = []
  1155.             row = 0
  1156.             col = 0
  1157.             checkCont = gtk.Table()
  1158.             for m in setting.Restrictions:
  1159.                 ss = gtk.CheckButton(m)
  1160.                 CheckInfo = FooClass()
  1161.                 CheckInfo.String = m
  1162.                 CheckInfo.Checkbox = ss
  1163.                 checkies = checkies+[CheckInfo]
  1164.                 checkCont.attach(ss,col,col+1,row,row+1)
  1165.                 col = col+1
  1166.                 if (col>3):
  1167.                     col = 0
  1168.                     row = row+1
  1169.             bar.pack_start(checkCont,True,True)
  1170.             SetInfo.CheckBoxes = checkies
  1171.             for bar in checkies:
  1172.                 bar.Checkbox.connect("toggled",SimpleChangedCB,SetInfo)
  1173.         else:
  1174.             foo = gtk.Frame(setting.ShortDesc)
  1175.             bar = gtk.HBox(False,8)
  1176.             ebox = gtk.EventBox()
  1177.             ebox.add(bar)
  1178.             bar.props.border_width = 4
  1179.             foo.add(ebox)
  1180.             tooltips.set_tip(ebox,setting.LongDesc)
  1181.             bil = gtk.ListStore(gobject.TYPE_STRING)
  1182.             foob = gtk.ScrolledWindow()
  1183.             foob.props.hscrollbar_policy = gtk.POLICY_NEVER
  1184.             foob.props.vscrollbar_policy = gtk.POLICY_AUTOMATIC
  1185.             foob.props.shadow_type = gtk.SHADOW_IN
  1186.             baz = gtk.TreeView(bil)
  1187.             foob.add(baz)
  1188.             ren = gtk.CellRendererText()
  1189.             ren.props.editable = True
  1190.             baz.insert_column_with_attributes(0,"Value",ren,text = 0)
  1191.             baz.props.headers_visible = False
  1192.             baz.props.height_request = 100
  1193.             fib = gtk.VBox()
  1194.             fib.pack_start(resbut,False,False)
  1195.             bar.pack_start(fib,False,False)
  1196.             bar.pack_start(foob,True,True)
  1197.             tab = gtk.Table(homogeneous = True)
  1198.             delete = gtk.Button()
  1199.             delete.props.image = gtk.image_new_from_stock(gtk.STOCK_REMOVE,gtk.ICON_SIZE_BUTTON)
  1200.             add = gtk.Button()
  1201.             add.props.image = gtk.image_new_from_stock(gtk.STOCK_ADD,gtk.ICON_SIZE_BUTTON)
  1202.             if setting.Plugin.Name == "state":
  1203.                 add.connect("clicked",StatePopup,SetInfo)
  1204.             else:
  1205.                 up = gtk.Button()
  1206.                 up.props.image = gtk.image_new_from_stock(gtk.STOCK_GO_UP,gtk.ICON_SIZE_BUTTON)
  1207.                 dn = gtk.Button()
  1208.                 dn.props.image = gtk.image_new_from_stock(gtk.STOCK_GO_DOWN,gtk.ICON_SIZE_BUTTON)
  1209.                 up.connect("clicked",MoveRow,(0,SetInfo))
  1210.                 dn.connect("clicked",MoveRow,(1,SetInfo))
  1211.                 add.connect("clicked",AddRow,SetInfo)
  1212.                 tab.attach(up,0,1,0,1)
  1213.                 tab.attach(dn,0,1,2,3)
  1214.             SetInfo.ListStore = bil
  1215.             SetInfo.TreeView = baz
  1216.             if (setting.HasHint("file")):
  1217.                 brw = gtk.Button(_("Browse"))
  1218.                 brw.props.image = gtk.image_new_from_stock(gtk.STOCK_OPEN,gtk.ICON_SIZE_BUTTON)
  1219.                 brw.connect("clicked",BrowseRow,SetInfo)
  1220.                 tooltips.set_tip(brw,setting.LongDesc)
  1221.                 tab.attach(brw,0,2,1,2)
  1222.             delete.connect("clicked",DelRow,SetInfo)
  1223.             tab.attach(add,1,2,0,1)
  1224.             tab.attach(delete,1,2,2,3)
  1225.             bar.pack_start(tab,False,False)
  1226.             ren.connect("edited",RowEdited,SetInfo)
  1227.         wid.attach(foo,0,2,Row,Row+1)
  1228.     elif (setting.Type == 'String'):
  1229.         foo = gtk.HBox(False,8)
  1230.         foo.pack_start(resbut,False,False)
  1231.         foo.pack_start(lab,False,False)
  1232.         ebox = gtk.EventBox()
  1233.         ebox.add(foo)
  1234.         wid.attach(ebox,0,1,Row,Row+1,gtk.SHRINK)
  1235.         tooltips.set_tip(ebox,setting.LongDesc)
  1236.         if (len(setting.Restrictions)):
  1237.             bar = gtk.combo_box_new_text()
  1238.             for m in setting.Restrictions:
  1239.                 bar.append_text(m)
  1240.             SetInfo.ComboBox = bar
  1241.         else:
  1242.             bar = gtk.Entry()
  1243.             bar.props.width_chars = 30
  1244.             SetInfo.Entry = bar
  1245.         foo = gtk.HBox(False,8)
  1246.         foo.pack_start(bar,True,True)
  1247.         ebox = gtk.EventBox()
  1248.         ebox.add(foo)
  1249.         tooltips.set_tip(ebox,setting.LongDesc)
  1250.         if (setting.HasHint("file")):
  1251.             bar.props.width_chars = 25
  1252.             brw = gtk.Button("Browse")
  1253.             brw.props.image = gtk.image_new_from_stock(gtk.STOCK_OPEN,gtk.ICON_SIZE_BUTTON)
  1254.             brw.connect("clicked",BrowseEntry,SetInfo)
  1255.             tooltips.set_tip(brw,setting.LongDesc)
  1256.             foo.pack_start(brw,False,False)
  1257.         wid.attach(ebox,1,2,Row,Row+1)
  1258.         bar.connect("changed",SimpleChangedCB,SetInfo)
  1259.     elif (setting.Type == 'Int' or setting.Type == 'Float'):
  1260.         foo = gtk.HBox(False,8)
  1261.         foo.pack_start(resbut,False,False)
  1262.         foo.pack_start(lab,False,False)
  1263.         ebox = gtk.EventBox()
  1264.         ebox.add(foo)
  1265.         tooltips.set_tip(ebox,setting.LongDesc)
  1266.         wid.attach(ebox,0,1,Row,Row+1,gtk.SHRINK)
  1267.         foo = gtk.HBox(False,8)
  1268.         if (len(setting.Restrictions)>2):
  1269.             Adj = gtk.Adjustment(setting.Value,setting.Restrictions[0],setting.Restrictions[1],setting.Restrictions[2])
  1270.             bat = gtk.SpinButton(Adj,setting.Restrictions[2],4)
  1271.             ban = gtk.HScale(Adj)
  1272.             tooltips.set_tip(ban,setting.LongDesc)
  1273.             ban.props.digits = 4
  1274.         else:
  1275.             Adj = gtk.Adjustment(setting.Value,setting.Restrictions[0],setting.Restrictions[1],1)
  1276.             bat = gtk.SpinButton(Adj,1,0)
  1277.             ban = gtk.HScale(Adj)
  1278.             tooltips.set_tip(ban,setting.LongDesc)
  1279.             ban.props.digits = 0
  1280.         ban.props.update_policy = gtk.UPDATE_DISCONTINUOUS
  1281.         bat.props.update_policy = gtk.UPDATE_IF_VALID
  1282.         ban.props.draw_value = False
  1283.         bat.props.width_chars = 6
  1284.         bat.set_editable(True)
  1285.         tooltips.set_tip(bat,setting.LongDesc)
  1286.         hb = gtk.HBox(False,8)
  1287.         wid.attach(hb,1,2,Row,Row+1)
  1288.         hb.pack_start(ban,True,True)
  1289.         hb.pack_start(bat,False,False)
  1290.         SetInfo.SpinButton = bat
  1291.         SetInfo.HScale = ban
  1292.         ban.connect("value-changed",SimpleChangedCB,SetInfo)
  1293.     elif (setting.Type == 'Color'):
  1294.         foo = gtk.HBox(False,8)
  1295.         foo.pack_start(resbut,False,False)
  1296.         foo.pack_start(lab,False,False)
  1297.         ebox = gtk.EventBox()
  1298.         ebox.add(foo)
  1299.         tooltips.set_tip(ebox,setting.LongDesc)
  1300.         wid.attach(ebox,0,1,Row,Row+1,gtk.SHRINK)
  1301.         foo = gtk.HBox(False,8)
  1302.         bar = gtk.ColorButton()
  1303.         tooltips.set_tip(bar,setting.LongDesc)
  1304.         foo.pack_start(bar,False,False)
  1305.         bar.props.use_alpha = True
  1306.         wid.attach(foo,1,2,Row,Row+1)
  1307.         SetInfo.ColorButton = bar
  1308.         bar.connect("color-set",SimpleChangedCB,SetInfo)
  1309.     else:
  1310.         return False
  1311.     lab.props.wrap = True
  1312.     lab.props.width_request = 250
  1313.     lab.props.xalign = 0
  1314.     Row = Row+1
  1315.     resbut.connect("clicked",ClearSet,SetInfo)
  1316.     AllSettings = AllSettings+[SetInfo]
  1317.     return True
  1318.  
  1319. def DoFilter(foo,Store):
  1320.     Store.refilter()
  1321.  
  1322. def MakeBindingsListForPlugin(Plugin):
  1323.     BindVBox = gtk.VBox(False,4)
  1324.     EntHBox = gtk.HBox(False,4)
  1325.     entry = gtk.Entry()
  1326.     clearbut = gtk.Button(gtk.STOCK_CLEAR)
  1327.     clearbut.set_use_stock(True)
  1328.     EntHBox.pack_start(gtk.Label(_("Search:")),False,False)
  1329.     EntHBox.pack_start(entry,True,True)
  1330.     EntHBox.pack_start(clearbut,False,False)
  1331.     BindVBox.pack_start(EntHBox,False,False)
  1332.     Store = gtk.TreeStore(
  1333.         gobject.TYPE_STRING,    #Entry Name
  1334.         gobject.TYPE_STRING,    #Key binding
  1335.         gobject.TYPE_BOOLEAN,    #key enabled
  1336.         gobject.TYPE_STRING,    #Button binding
  1337.         gobject.TYPE_BOOLEAN,    #button enabled
  1338.         gobject.TYPE_STRING,    #setting name
  1339.             )
  1340.     StoreFiltered = Store.filter_new()
  1341.     View = gtk.TreeView(StoreFiltered)
  1342.     Scroll = gtk.ScrolledWindow()
  1343.     Scroll.props.hscrollbar_policy = gtk.POLICY_NEVER
  1344.     Scroll.add(View)
  1345.     vwinfr = gtk.Frame()
  1346.     vwinfr.props.shadow_type = gtk.SHADOW_IN
  1347.     vwinfr.add(Scroll)
  1348.     BindVBox.pack_start(vwinfr,True,True)
  1349.     nameren = gtk.CellRendererText()
  1350.     View.insert_column_with_attributes(0,_("Name"),nameren,markup = 0)
  1351.     keyren = gtk.CellRendererText()
  1352.     View.insert_column_with_attributes(1,_("Keyboard"),keyren,text = 1,editable = 2,sensitive = 2)
  1353.     butren = gtk.CellRendererText()
  1354.     View.insert_column_with_attributes(2,_("Mouse"),butren,text = 3,editable = 4,sensitive = 4)
  1355.     View.props.headers_visible = True
  1356.     View.props.rules_hint = True
  1357.     hasany = False
  1358.  
  1359.     StoreFiltered.set_visible_func(BindingIsVisibleMethod,entry)
  1360.  
  1361.     for G in Plugin.Groups:
  1362.         GSettings = [S for S in Plugin.Settings if S.Group == G.Name and S.Type == 'Binding'
  1363.                 and (S.Restrictions[0] or S.Restrictions[1])]
  1364.         if len(G.SubGroups) and not (G.Name == '') and len(GSettings):
  1365.             GIter = Store.append(None)
  1366.             Store.set(GIter,0,G.Name)
  1367.         else:
  1368.             GIter = None
  1369.         for S in GSettings:
  1370.             hasany = True
  1371.             Iter = Store.append(GIter)
  1372.             if (S.Restrictions[0]):
  1373.                 mv0 = S.Value[0]
  1374.             else:
  1375.                 mv0 = "N/A"
  1376.             if (S.Restrictions[1]):
  1377.                 mv1 = S.Value[1]
  1378.             else:
  1379.                 mv1 = "N/A"
  1380.             if (S.Integrated):
  1381.                 Store.set(Iter,0,"<span foreground=\"blue\">%s</span>"%(S.ShortDesc),1,mv0,2,S.Restrictions[0] and not S.ReadOnly,
  1382.                         3,mv1,4,S.Restrictions[1] and not S.ReadOnly,5,S.Name)
  1383.             else:
  1384.                 Store.set(Iter,0,S.ShortDesc,1,mv0,2,S.Restrictions[0] and not S.ReadOnly,
  1385.                         3,mv1,4,S.Restrictions[1] and not S.ReadOnly,5,S.Name)
  1386.  
  1387.     Info = FooClass()
  1388.     Info.Plugin = Plugin
  1389.     Info.Store = Store
  1390.     Info.StoreFiltered = StoreFiltered
  1391.  
  1392.     clearbut.connect("clicked",ClearEntry,entry)
  1393.     entry.connect("changed",DoFilter,StoreFiltered)
  1394.  
  1395.     View.connect("row-activated",BindingPopup,Info)
  1396.     keyren.connect("edited",BindChanged,(0,Info))
  1397.     butren.connect("edited",BindChanged,(1,Info))
  1398.  
  1399.     if hasany:
  1400.         return BindVBox
  1401.     return None
  1402.  
  1403. def ProfileSelChanged(sel,ent):
  1404.     Inf = sel.get_selected()
  1405.     if Inf[1] and Inf[0].get(Inf[1],0)[0]:
  1406.         ent.set_text(Inf[0].get(Inf[1],0)[0])
  1407.     else:
  1408.         ent.set_text('')
  1409.  
  1410. def MakeProfileWidgets():
  1411.     global CurProfLab
  1412.     global CurProfStore
  1413.     global CurProfView
  1414.     all = gtk.VBox(False,4)
  1415.     CurProfLab = gtk.Label()
  1416.     CurProfLab.props.xalign = 0
  1417.     all.pack_start(CurProfLab,False,False)
  1418.     row = gtk.HBox(False,4)
  1419.     all.pack_start(row,False,False)
  1420.     ent = gtk.Entry()
  1421.     row.pack_start(ent,True,True)
  1422.     addchbut = gtk.Button(_('Add/Save'))
  1423.     row.pack_start(addchbut,False,False)
  1424.     loadbut = gtk.Button(_('Load/Activate'))
  1425.     row.pack_start(loadbut,False,False)
  1426.     delbut = gtk.Button(_('Delete'))
  1427.     row.pack_start(delbut,False,False)
  1428.     CurProfStore = gtk.ListStore(gobject.TYPE_STRING)
  1429.     CurProfView = gtk.TreeView(CurProfStore)
  1430.     vwin = gtk.ScrolledWindow()
  1431.     vwinfr = gtk.Frame()
  1432.     vwinfr.props.shadow_type = gtk.SHADOW_IN
  1433.     vwin.props.hscrollbar_policy = gtk.POLICY_NEVER
  1434.     vwin.props.vscrollbar_policy = gtk.POLICY_AUTOMATIC
  1435.     vwin.add(CurProfView)
  1436.     texren = gtk.CellRendererText()
  1437.     CurProfView.insert_column_with_attributes(0,"Profile",texren,text = 0)
  1438.     vwinfr.add(vwin)
  1439.     all.pack_start(vwinfr,True,True)
  1440.     viewsel = CurProfView.get_selection()
  1441.     viewsel.connect("changed",ProfileSelChanged,ent)
  1442.     CurProfView.connect("row-activated",ProfileRowActive,ent)
  1443.     UpdateProfileStore()
  1444.     addchbut.connect("clicked",SaveProfile,ent)
  1445.     loadbut.connect("clicked",LoadProfile,ent)
  1446.     delbut.connect("clicked",DeleteProfile,ent)
  1447.     return all
  1448.  
  1449. def ProfileRowActive(wid,path,col,ent):
  1450.     LoadProfile(None,ent)
  1451.  
  1452. def SaveProfile(wid,ent):
  1453.     val = ent.get_text()
  1454.     if (val == ''):
  1455.         return # silently ignore this silliness
  1456.     if (val == _('<Default>')):
  1457.         val = None
  1458.     Ctx.Profile = val
  1459.     WriteSettings()
  1460.     UpdateProfileStore()
  1461.  
  1462. def LoadProfile(wid,ent):
  1463.     val = ent.get_text()
  1464.     if (val == ''):
  1465.         return # silently ignore this silliness
  1466.     if (val == _('<Default>')):
  1467.         val = None
  1468.     Ctx.Profile = val
  1469.     Ctx.Read()
  1470.     SetWidgetsFromValues()
  1471.     WriteSettings()
  1472.     UpdateProfileStore()
  1473.  
  1474. def DeleteProfile(wid,ent):
  1475.     val = ent.get_text()
  1476.     if (val == ''):
  1477.         return # silently ignore this silliness
  1478.     if (val == _('<Default>')):
  1479.         val = None
  1480.     Ctx.DeleteProfile(val)
  1481.     if (Ctx.Profile == val):
  1482.         Ctx.Profile = None
  1483.         Ctx.Read()
  1484.     SetWidgetsFromValues()
  1485.     WriteSettings()
  1486.     UpdateProfileStore()
  1487.  
  1488. def UpdateProfileStore():
  1489.     global CurProfStore
  1490.     global CurProfView
  1491.     CurProfStore.clear()
  1492.     viewsel = CurProfView.get_selection()
  1493.     Iter = CurProfStore.append()
  1494.     CurProfStore.set(Iter,0,_('<Default>'))
  1495.     if not Ctx.Profile:
  1496.         viewsel.select_iter(Iter)
  1497.     for p in Ctx.Profiles:
  1498.         Iter = CurProfStore.append()
  1499.         CurProfStore.set(Iter,0,p)
  1500.         if p == Ctx.Profile:
  1501.             viewsel.select_iter(Iter)
  1502.  
  1503. def MakeBackendWidgets():
  1504.     tab = gtk.Table()
  1505.     BackendStore = gtk.ListStore(gobject.TYPE_STRING,gobject.TYPE_STRING,gobject.TYPE_BOOLEAN)
  1506.     for backend in berylsettings.Backends():
  1507.         Iter = BackendStore.append()
  1508.         BackendStore.set(Iter,0,backend.Name,1,backend.ShortDesc,2,backend.IntegrationSupport)
  1509.     BackendBox = gtk.ComboBox(BackendStore)
  1510.     BackendRend = gtk.CellRendererText()
  1511.     BackendBox.pack_start(BackendRend)
  1512.     BackendBox.add_attribute(BackendRend,"text",1)
  1513.     lab = gtk.Label(_('DE and Settings Backend'))
  1514.     lab.props.wrap = True
  1515.     lab.props.width_request = 250
  1516.     lab.props.xalign = 0
  1517.     tab.attach(lab,0,1,0,1)
  1518.     tab.attach(BackendBox,1,2,0,1)
  1519.     actv = Ctx.Backend
  1520.     Iter = BackendStore.get_iter_first()
  1521.  
  1522.     lab = gtk.Label(_("Enable DE Integration for Backend"))
  1523.     lab.props.wrap = True
  1524.     lab.props.width_request = 250
  1525.     lab.props.xalign = 0
  1526.     tab.attach(lab,0,1,1,2)
  1527.     IntegButton = gtk.CheckButton()
  1528.     IntegButton.set_active(Ctx.Integrated)
  1529.     tab.attach(IntegButton,1,2,1,2)
  1530.  
  1531.     while(True):
  1532.         m = BackendStore.get(Iter,0,2)
  1533.         if (m[0]==actv):
  1534.             BackendBox.set_active_iter(Iter)
  1535.             IntegButton.set_sensitive(m[1])
  1536.             break
  1537.         Iter = BackendStore.iter_next(Iter)
  1538.         if not Iter:
  1539.             break
  1540.  
  1541.     BackendBox.connect("changed",SetActiveBackend,(BackendStore,IntegButton))
  1542.     IntegButton.connect("toggled",SetIntegrated)
  1543.  
  1544.     tabBox = gtk.VBox(False,0)
  1545.     tabBox.pack_start(tab,False,False)
  1546.  
  1547.     return tabBox
  1548.  
  1549. def MakeSubGroupArea(SubGroup,GroupVBox):
  1550.     global Row
  1551.     if (SubGroup.Name == '__keymouse'):
  1552.         UpdateBindingsList(False)
  1553.         GroupVBox.pack_start(MakeBindingsList(),True,True)
  1554.         return True
  1555.     if (SubGroup.Name == '__shortcuts_for_plugin'):
  1556.         wid = MakeBindingsListForPlugin(SubGroup.Plugin)
  1557.         if (wid):
  1558.             GroupVBox.pack_start(wid,True,True)
  1559.             return True
  1560.         return False
  1561.     if (SubGroup.Name == '__edges'):
  1562.         GroupVBox.pack_start(MakeEdgeWidgets(),True,True)
  1563.         return True
  1564.     if (SubGroup.Name == '__profiles'):
  1565.         GroupVBox.pack_start(MakeProfileWidgets(),True,True)
  1566.         return True
  1567.     if (SubGroup.Name == '__backends'):
  1568.         GroupVBox.pack_start(MakeBackendWidgets(),True,True)
  1569.         return True
  1570.     GroupContainer = GroupVBox
  1571.     Frame = None
  1572.     if not SubGroup.Name == '':
  1573.         Frame = gtk.Frame()
  1574.         Expander = gtk.Expander(SubGroup.Name)
  1575.         Frame.add(Expander)
  1576.         GroupContainer = gtk.VBox()
  1577.         Expander.add(GroupContainer)
  1578.     hasany = False
  1579.     Table = gtk.Table()
  1580.     Table.props.row_spacing = 4
  1581.     Row = 0
  1582.     GroupContainer.pack_start(Table,False,False)
  1583.     for Setting in SubGroup.Settings:
  1584.         if (not Setting.Advanced):
  1585.             if (MakeAndConnect(Table,Setting)):
  1586.                 hasany = True
  1587.     AdvFrame = gtk.Frame()
  1588.     AdvExpander = gtk.Expander(_("Advanced"))
  1589.     AdvFrame.add(AdvExpander)
  1590.     AdvVBox = gtk.VBox()
  1591.     AdvExpander.add(AdvVBox)
  1592.     AdvTable = gtk.Table()
  1593.     AdvTable.props.row_spacing = 4
  1594.     Row = 0
  1595.     AdvVBox.pack_start(AdvTable,False,False)
  1596.     hasAdvanced = False
  1597.     for Setting in SubGroup.Settings:
  1598.         if (Setting.Advanced):
  1599.             if (MakeAndConnect(AdvTable,Setting)):
  1600.                 hasAdvanced = True
  1601.                 hasany = True
  1602.     if hasAdvanced:
  1603.         GroupContainer.pack_start(AdvFrame,False,False)
  1604.         #otherwise it just falls out of scope
  1605.     if (hasany and Frame):
  1606.         GroupVBox.pack_start(Frame,False,False)
  1607.         #same as above
  1608.     return hasany
  1609.  
  1610. def MakeGroupArea(Group,NoteBook):
  1611.     VBox = gtk.VBox(False,4)
  1612.     Viewport = gtk.Viewport()
  1613.     Viewport.props.shadow_type = gtk.SHADOW_NONE
  1614.     ScrollWin = gtk.ScrolledWindow()
  1615.     ScrollWin.props.hscrollbar_policy = gtk.POLICY_NEVER
  1616.     ScrollWin.props.vscrollbar_policy = gtk.POLICY_AUTOMATIC
  1617.     Viewport.add(VBox)
  1618.     ScrollWin.add(Viewport)
  1619.     hasany = False
  1620.     NoteBook.append_page(ScrollWin,gtk.Label(Group.Name))
  1621.     VBox.props.border_width = 4
  1622.     for SubGroup in Group.SubGroups:
  1623.         if (MakeSubGroupArea(SubGroup,VBox)):
  1624.             hasany = True
  1625.     if not hasany:
  1626.         NoteBook.remove_page(-1)
  1627.  
  1628. def MakePluginArea(Plugin):
  1629.     global hideshowall
  1630.     Image = gtk.Image()
  1631.     if (Plugin.Name == '__bindings'):
  1632.         try:
  1633.             BasePixbuf = gdk.pixbuf_new_from_file_at_size(IMAGEDIR+"/shortcuts.svg",IconSize,IconSize)
  1634.         except:
  1635.             BasePixbuf = gdk.pixbuf_new_from_file_at_size(PREFIX+"/share/beryl/icon.png",IconSize,IconSize)
  1636.     elif (Plugin.Name == '__settings'):
  1637.         try:
  1638.             BasePixbuf = gdk.pixbuf_new_from_file_at_size(IMAGEDIR+"/profile-backends.svg",IconSize,IconSize)
  1639.         except:
  1640.             BasePixbuf = gdk.pixbuf_new_from_file_at_size(PREFIX+"/share/beryl/icon.png",IconSize,IconSize)
  1641.     else:
  1642.         try:
  1643.             BasePixbuf = gdk.pixbuf_new_from_file_at_size(IMAGEDIR+"/beryl-settings-section-%s.svg"%(Plugin.Name),IconSize,IconSize)
  1644.         except:
  1645.             try:
  1646.                 BasePixbuf = gdk.pixbuf_new_from_file_at_size(IMAGEDIR+"/beryl-settings-section-%s.png"%(Plugin.Name),IconSize,IconSize)
  1647.             except:
  1648.                 BasePixbuf = gdk.pixbuf_new_from_file_at_size(PREFIX+"/share/beryl/icon.png",IconSize,IconSize)
  1649.     HighPixbuf = BasePixbuf.copy()
  1650.     HighPixbuf.saturate_and_pixelate(HighPixbuf,6.0,True)
  1651.     Image.set_from_pixbuf(BasePixbuf)
  1652.     ListEventBox = gtk.EventBox()
  1653.     ListHBox = gtk.HBox(False,8)
  1654.     ListEventBox.add(ListHBox)
  1655.     if (not (Category.Name == '__general')):
  1656.         EnableButton = gtk.CheckButton()
  1657.         ListHBox.pack_start(EnableButton,False,False)
  1658.     else:
  1659.         EnableButton = None
  1660.     ListHBox.pack_start(Image,False,False)
  1661.     Label = gtk.Label()
  1662.     Label.set_markup("<small>%s</small>"%(Plugin.ShortDesc))
  1663.     Label.set_size_request(120,-1)
  1664.     Label.set_line_wrap(True)
  1665.     ListHBox.pack_start(Label,False,False)
  1666.     Container = gtk.VBox(False,4)
  1667.     HeaderBox = gtk.HBox(False,8)
  1668.     HeaderImage = gtk.Image()
  1669.     HeaderImage.set_from_pixbuf(BasePixbuf)
  1670.     HeaderBox.pack_start(HeaderImage,False,False,0)
  1671.     HeaderLabel = gtk.Label()
  1672.     HeaderLabel.set_markup("<b><big>%s</big></b>\n<i>%s</i>"%(Plugin.ShortDesc,Plugin.LongDesc))
  1673.     HeaderLabel.props.wrap = True
  1674.     if (HeaderLabel.size_request()[0]>400):
  1675.         HeaderLabel.props.width_request = 400
  1676.     HeaderLabel.props.xalign = 0
  1677.     HeaderBox.pack_start(HeaderLabel,True,True,0)
  1678.     Container.pack_start(HeaderBox,False,False)
  1679.     if (Plugin.Name == '__bindings'):
  1680.         hideshowall = gtk.CheckButton(_("Show Disabled Plugins"))
  1681.         hideshowall.props.active = False
  1682.         hideshowall.connect("clicked",HideShowClick)
  1683.         Container.pack_start(hideshowall,False,False)
  1684.  
  1685.     NoteBook = gtk.Notebook()
  1686.     NoteBook.props.scrollable = True
  1687.     Container.pack_start(NoteBook,True,True)
  1688.  
  1689.     for Group in Plugin.Groups:
  1690.         MakeGroupArea(Group,NoteBook)
  1691.  
  1692.     if (not Category.Name == "__general" or Plugin.Name == '_'):
  1693.         BindGroup = FooClass()
  1694.         BindSubGroup = FooClass()
  1695.         BindGroup.Name = _('Shortcuts')
  1696.         BindGroup.SubGroups = [BindSubGroup]
  1697.         BindSubGroup.Name = '__shortcuts_for_plugin'
  1698.         BindSubGroup.Plugin = Plugin
  1699.         MakeGroupArea(BindGroup,NoteBook)
  1700.  
  1701.     Info = FooClass()
  1702.  
  1703.     Info.BasePixbuf = BasePixbuf
  1704.     Info.HighPixbuf = HighPixbuf
  1705.     Info.Image = Image
  1706.     Info.Label = Label
  1707.     Info.Plugin = Plugin
  1708.     Info.Widget = Container
  1709.     Info.Button = EnableButton
  1710.     Info.ListEventBox = ListEventBox
  1711.     if EnableButton:
  1712.         Info.HasEnableButton = True
  1713.         Info.EnableButton = EnableButton
  1714.     else:
  1715.         Info.HasEnableButton = False
  1716.     return Info
  1717.  
  1718. def MakeCategoryArea(Category):
  1719.     global AllCats
  1720.     global Row
  1721.     Image = gtk.Image()
  1722.  
  1723.     CatBasePixbuf = gdk.pixbuf_new_from_file_at_size("%s/%s"%(BaseDir,CatImages[Category.Name]),IconSize,IconSize)
  1724.  
  1725.     HighPixbuf = CatBasePixbuf.copy()
  1726.     HighPixbuf.saturate_and_pixelate(HighPixbuf,6.0,True)
  1727.     Image.set_from_pixbuf(CatBasePixbuf)
  1728.     Label = gtk.Label()
  1729.     Label.set_markup("<small>%s</small>"%(Category.ShortDesc))
  1730.     Label.props.wrap = True
  1731.     Label.props.width_request = MaxWidth
  1732.     Label.props.justify = gtk.JUSTIFY_CENTER
  1733.     ListEventBox = gtk.EventBox()
  1734.     VBox = gtk.VBox()
  1735.     VBox.pack_start(Image,False,False)
  1736.     VBox.pack_end(Label,True,True)
  1737.     ListEventBox.add(VBox)
  1738.     CategoryBox.pack_start(ListEventBox)
  1739.     Container = gtk.VBox()
  1740.     HeaderBox = gtk.HBox()
  1741.     Container.pack_start(HeaderBox,False,False)
  1742.     HeaderImage = gtk.Image()
  1743.     HeaderImage.set_from_pixbuf(CatBasePixbuf)
  1744.     HeaderBox.pack_start(HeaderImage,False,False,8)
  1745.     HeaderLabel = gtk.Label()
  1746.     HeaderLabel.set_markup("<b><big>%s</big></b>\n<i>%s</i>"%(Category.ShortDesc,Category.LongDesc))
  1747.     HeaderLabel.props.xalign = 0
  1748.     HeaderBox.pack_start(HeaderLabel,True,True,8)
  1749.     FormatBox = gtk.HBox(False,0)
  1750.     Container.pack_start(FormatBox,True,True,8)
  1751.     ContentFrame = gtk.Frame()
  1752.     FormatBox.pack_start(ContentFrame,True,True,8)
  1753.     ContentHBox = gtk.HBox(False,8)
  1754.     PluginListFrame = gtk.Frame()
  1755.     PluginListScrollWin = gtk.ScrolledWindow()
  1756.     PluginListViewport = gtk.Viewport()
  1757.     PluginListViewport.props.shadow_type = gtk.SHADOW_NONE
  1758.     PluginListScrollWin.props.hscrollbar_policy = gtk.POLICY_NEVER
  1759.     PluginListScrollWin.props.vscrollbar_policy = gtk.POLICY_AUTOMATIC
  1760.     PluginList = gtk.VBox()
  1761.     PluginListViewport.add(PluginList)
  1762.     PluginListScrollWin.add(PluginListViewport)
  1763.     PluginList.props.border_width = 4
  1764.     PluginListFrame.add(PluginListScrollWin)
  1765.     ContentHBox.pack_start(PluginListFrame,False,False,0)
  1766.     ContentHBox.props.border_width = 8
  1767.     ContentFrame.add(ContentHBox)
  1768.     PluginContainer = gtk.Alignment()
  1769.     PluginContainer.props.xalign = 0
  1770.     PluginContainer.props.yalign = 0
  1771.     PluginContainer.props.xscale = 1
  1772.     PluginContainer.props.yscale = 1
  1773.     ContentHBox.pack_start(PluginContainer,True,True,0)
  1774.     Plugins = []
  1775.     SortedPluginList = Category.Plugins
  1776.     #alpha-sort plugin list
  1777.     if not Category.Name == '__general':
  1778.         for j in range(0,len(SortedPluginList)-1):
  1779.             for k in range(j+1,len(SortedPluginList)):
  1780.                 if (SortedPluginList[j].ShortDesc>SortedPluginList[k].ShortDesc):
  1781.                     TempStorage = SortedPluginList[j]
  1782.                     SortedPluginList[j] = SortedPluginList[k]
  1783.                     SortedPluginList[k] = TempStorage
  1784.     for Plugin in SortedPluginList:
  1785.         if (Plugin.Name == '_' and not (Category.Name == '__general')):
  1786.             continue
  1787.         PlugInfo = MakePluginArea(Plugin)
  1788.         PlugInfo.CatIndex = len(AllCats)
  1789.         PlugInfo.Index = len(Plugins)
  1790.         Plugins = Plugins+[PlugInfo]
  1791.         PlugInfo.ListEventBox.connect("button-press-event",PlugClicked,PlugInfo)
  1792.         if (PlugInfo.HasEnableButton):
  1793.             PlugInfo.EnableButton.connect("toggled",PluginButtonClicked,PlugInfo)
  1794.         PluginList.pack_start(PlugInfo.ListEventBox,False,False)
  1795.  
  1796.     CatInfo = FooClass()
  1797.     CatInfo.BasePixbuf = CatBasePixbuf
  1798.     CatInfo.HighPixbuf = HighPixbuf
  1799.     CatInfo.Image = Image
  1800.     CatInfo.Label = Label
  1801.     CatInfo.Widget = Container
  1802.     CatInfo.Category = Category
  1803.     CatInfo.Index = len(AllCats)
  1804.     CatInfo.Plugins = Plugins
  1805.     CatInfo.Container = PluginContainer
  1806.     AllCats = AllCats+[CatInfo]
  1807.     ListEventBox.connect("button-press-event",CatClicked,CatInfo)
  1808.  
  1809. def ImportSettings(wid):
  1810.     ImportWindow = gtk.FileChooserDialog(_("Import settings file..."),MainWindow,
  1811.             gtk.FILE_CHOOSER_ACTION_OPEN,(gtk.STOCK_OPEN,gtk.RESPONSE_OK,
  1812.                 gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL))
  1813.     fil = gtk.FileFilter()
  1814.     fil.set_name(_("All Files"))
  1815.     fil.add_pattern("*")
  1816.     ImportWindow.add_filter(fil)
  1817.     ImportWindow.set_filter(fil)
  1818.     ret = ImportWindow.run()
  1819.     if (ret == gtk.RESPONSE_OK):
  1820.         val = ImportWindow.get_filename()
  1821.         if (val):
  1822.             Ctx.Import(val,True)
  1823.     ImportWindow.destroy()
  1824.     del ImportWindow
  1825.  
  1826. def ExportSettings(wid):
  1827.     ExportWindow = gtk.FileChooserDialog(_("Export settings file..."),MainWindow,
  1828.             gtk.FILE_CHOOSER_ACTION_SAVE,(gtk.STOCK_SAVE,gtk.RESPONSE_OK,
  1829.                 gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL))
  1830.     fil = gtk.FileFilter()
  1831.     fil.set_name(_("Settings Files"))
  1832.     fil.add_pattern("*.settings")
  1833.     ExportWindow.set_filter(fil)
  1834.     ret = ExportWindow.run()
  1835.     if (ret == gtk.RESPONSE_OK):
  1836.         val = ExportWindow.get_filename()
  1837.         if (val):
  1838.             Ctx.Export(val)
  1839.     ExportWindow.destroy()
  1840.     del ExportWindow
  1841.  
  1842. def SetActiveBackend(wid,info):
  1843.     Iter = wid.get_active_iter()
  1844.     dat = info[0].get(Iter,0,2)
  1845.     Ctx.Backend = dat[0]
  1846.     info[1].set_sensitive(dat[1])
  1847.     UpdateProfileStore()
  1848.     SetWidgetsFromValues()
  1849.  
  1850. def SetIntegrated(wid):
  1851.     Ctx.Integrated = wid.props.active
  1852.     SetWidgetsFromValues()
  1853.  
  1854. MainWindow = gtk.Window()
  1855. MainChild = gtk.VBox()
  1856. MainWindow.add(MainChild)
  1857. version = VERSION
  1858. MainWindow.set_title(_("Beryl Settings Manager"))
  1859. try:
  1860.     MainWindow.set_icon (gdk.pixbuf_new_from_file(DATADIR+"/icons/hicolor/scalable/apps/beryl-settings.svg"))
  1861. except:
  1862.     pass
  1863. #MainWindow.set_resizable(False)
  1864. MainWindow.set_size_request(-1,580) #MainWindow.get_size_request()[0],580)
  1865. CategoryStrip = gtk.Alignment()
  1866. CategoryStrip.props.xalign = 0.5
  1867. CategoryStrip.props.yalign = 0.5
  1868. CategoryStrip.props.xscale = 0
  1869. CategoryStrip.props.yscale = 0
  1870. CategoryBox = gtk.HBox(True)
  1871. CategoryStrip.add(CategoryBox)
  1872. PlugArea = gtk.Alignment()
  1873. PlugArea.props.xalign = 0
  1874. PlugArea.props.yalign = 0
  1875. PlugArea.props.xscale = 1
  1876. PlugArea.props.yscale = 1
  1877. MainChild.pack_start(CategoryStrip,False,False)
  1878. MainChild.pack_start(gtk.HSeparator(),False,False)
  1879. MainChild.pack_start(gtk.HSeparator(),False,False)
  1880. MainChild.pack_start(PlugArea,True,True)
  1881. ButtonRow = gtk.HBox()
  1882. ButtonRow.props.border_width = 0
  1883. MainChild.pack_start(ButtonRow,False,False)
  1884. MainChild.pack_start(gtk.Alignment(),False,False,4)
  1885.  
  1886. ImportButton = gtk.Button(_("Import"))
  1887. ImportButton.props.image = gtk.image_new_from_stock(gtk.STOCK_OPEN,gtk.ICON_SIZE_BUTTON)
  1888. ButtonRow.pack_start(ImportButton,False,False,8)
  1889. ImportButton.connect("clicked",ImportSettings)
  1890.  
  1891. ExportButton = gtk.Button(_("Export"))
  1892. ExportButton.props.image = gtk.image_new_from_stock(gtk.STOCK_SAVE,gtk.ICON_SIZE_BUTTON)
  1893. ButtonRow.pack_start(ExportButton,False,False,0)
  1894. ExportButton.connect("clicked",ExportSettings)
  1895.  
  1896. QButton = gtk.Button(gtk.STOCK_QUIT)
  1897. QButton.set_use_stock(True)
  1898. ButtonRow.pack_end(QButton,False,False,8)
  1899. QButton.connect("clicked",QuitAll)
  1900.  
  1901. IconSize = 48
  1902. MaxWidth = 112
  1903.  
  1904. Bind = FooClass()
  1905. Edge = FooClass()
  1906. NonCat = FooClass()
  1907. KeyMouse = FooClass()
  1908. EdSub = FooClass()
  1909. EdSub.Name = "__edges"
  1910. Edge.Name = _("Screen Edges")
  1911. Edge.SubGroups = [EdSub]
  1912. KeyMouse.Name = _("Keyboard and Mouse")
  1913. BindSub = FooClass()
  1914. BindSub.Name = "__keymouse"
  1915. KeyMouse.SubGroups = [BindSub]
  1916. Bind.Name = "__bindings"
  1917. Bind.ShortDesc = _("Shortcuts")
  1918. Bind.LongDesc = _('Key, Mouse and Edge Shortcuts (Bindings)')
  1919. Bind.Groups = [KeyMouse,Edge]
  1920.  
  1921. SettProf = FooClass()
  1922. SettProf.Name = _('Profiles')
  1923. SettPSub = FooClass()
  1924. SettPSub.Name = '__profiles'
  1925. SettProf.SubGroups = [SettPSub]
  1926. SettBack = FooClass()
  1927. SettBack.Name = _('Backends and Integration')
  1928. SettBSub = FooClass()
  1929. SettBSub.Name = '__backends'
  1930. SettBack.SubGroups = [SettBSub]
  1931. Sett = FooClass()
  1932. Sett.Groups = [SettProf,SettBack]
  1933. Sett.Name = "__settings"
  1934. Sett.ShortDesc = _('Settings, Profiles and Desktop Integration')
  1935. Sett.LongDesc = _('Options for Settings storage, Settings Profiles, and Desktop Integration')
  1936. NonCat.Name = '__general'
  1937. NonCat.ShortDesc = _('General Options')
  1938. NonCat.LongDesc = _('Beryl Core Options - Options which are part of the core of beryl, and are not part of the plugins.')
  1939. NonCat.Plugins = [Ctx.Plugin("_"),Bind,Sett]
  1940.  
  1941. for Category in [NonCat]+Ctx.Categories:
  1942.     if (Category.Name == "settings"):
  1943.         continue
  1944.     if (len(Category.Plugins) == 1):
  1945.         if (Category.Plugins[0].Name == "_"):
  1946.             continue
  1947.     if (len(Category.Plugins)>0):
  1948.         MakeCategoryArea(Category)
  1949.  
  1950. SetWidgetsFromValues()
  1951. CatClicked(None,None,AllCats[0])
  1952. for Cat in AllCats:
  1953.     PlugClicked(None,None,Cat.Plugins[0])
  1954. MainWindow.connect("destroy",QuitAll)
  1955. MainWindow.show_all()
  1956. gtk.main()
  1957.