#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Authors: Quinn Storm (quinn@beryl-project.org)
# Patrick Niklaus (marex@opencompositing.org)
# Copyright (C) 2007 Quinn Storm
import pygtk
import gtk
import gobject
import os
import mimetypes
mimetypes.init()
from ccm.Constants import *
from ccm.Conflicts import *
from ccm.Utils import *
import locale
import gettext
locale.setlocale(locale.LC_ALL, "")
gettext.bindtextdomain("ccsm", DataDir + "/locale")
gettext.textdomain("ccsm")
_ = gettext.gettext
CurrentUpdater = None
class Setting:
def __init__(self, Setting, createUpdater=True):
global CurrentUpdater
self.Custom = False
self.Setting = Setting
self.Blocked = 0
self.MakeLabel()
self.Reset = gtk.Button()
Tooltips.set_tip(self.Reset,_("Reset setting to the default value"))
self.Reset.set_image(gtk.image_new_from_stock(
gtk.STOCK_CLEAR, gtk.ICON_SIZE_BUTTON))
self.Reset.connect('clicked', self.DoReset)
self._Init()
if createUpdater and CurrentUpdater == None:
context = None
if self.Setting.__class__ == list:
context = self.Setting[0].Plugin.Context
else:
context = self.Setting.Plugin.Context
CurrentUpdater = Updater(context)
CurrentUpdater.Append(self)
def Attach(self, table, row):
self.Reset.set_sensitive(not self.Setting.ReadOnly)
self.Widget.set_sensitive(not self.Setting.ReadOnly)
if self.Custom:
table.attach(self.Widget, 0, 100, row, row+1, TableDef, TableDef, TableX, TableX)
else:
table.attach(self.Label, 0, 1, row, row+1, gtk.FILL, TableDef, TableX, TableX)
table.attach(self.Widget, 1, 99, row, row+1, TableDef, TableDef, TableX, TableX)
table.attach(self.Reset, 99, 100, row, row+1, 0, TableDef, TableX, TableX)
def PureVirtual(self, str):
raise PureVirtualError, str, self.Setting.Name
def _Init(self):
self.PureVirtual('_Init')
def DoReset(self, foo):
self.Setting.Reset()
self.Setting.Plugin.Context.Write()
self.Read()
def MakeLabel(self):
self.Label = gtk.EventBox()
label = gtk.Label()
if self.Setting.Integrated:
label.set_markup("<span foreground=\"blue\">%s</span>" % self.Setting.ShortDesc)
else:
label.set_markup("<span>%s</span>" % self.Setting.ShortDesc)
self.Label.add(label)
Tooltips.set_tip(self.Label, self.Setting.LongDesc)
label.props.xalign = 0
label.props.wrap_mode = gtk.WRAP_WORD
label.set_size_request(160, -1)
label.set_line_wrap(True)
def Block(self):
self.Blocked = self.Blocked+1
def UnBlock(self):
self.Blocked = self.Blocked-1
def Read(self):
self.Block()
self._Read()
self.UnBlock()
def _Read(self):
self.PureVirtual('_Read')
def Changed(self, *args, **kwargs):
if self.Blocked <= 0:
self._Changed()
self.Setting.Plugin.Context.Write()
def _Changed(self):
self.PureVirtual('_Changed')
class StringMatchSetting(Setting):
def _Init(self):
self.Entry = gtk.Entry()
Tooltips.set_tip(self.Entry, self.Setting.LongDesc)
self.Entry.connect('activate', self.Changed)
self.Entry.connect('focus-out-event', self.Changed)
self.Widget = self.Entry
def _Read(self):
self.Entry.set_text(self.Setting.Value)
def _Changed(self):
self.Setting.Value = self.Entry.get_text()
class FileSetting:
def __init__(self, Setting):
self.Setting = Setting
self.Open = gtk.Button()
Tooltips.set_tip(self.Open, _("Browse for ") + self.Setting.LongDesc)
self.Open.set_image(gtk.image_new_from_stock(
gtk.STOCK_OPEN, gtk.ICON_SIZE_BUTTON))
self.Open.connect('clicked', self.OpenFileChooser)
def CreateFilter(self):
filter = gtk.FileFilter()
if len(self.Setting.Hints) > 1:
if self.Setting.Hints[1] == 'image':
filter.set_name(_("Images"))
filter.add_pattern("*.png")
filter.add_pattern("*.jpg")
filter.add_pattern("*.jpeg")
filter.add_pattern("*.svg")
else:
filter.add_pattern("*.*")
else:
filter.add_pattern("*")
filter.set_name(_("File"))
return filter
def CheckFileType(self, filename):
if filename.find(".") == -1:
return True
ext = filename.split(".")[-1]
try:
mime = mimetypes.types_map["." + ext]
except:
return True
if len(self.Setting.Hints) > 1:
if self.Setting.Hints[1] == 'image':
require = FeatureRequirement(self.Setting.Plugin.Context, 'imagemime:' + mime)
return require.Resolve()
return True
def OpenFileChooser(self, widget, custom_value=None):
value = self.Setting.Value
if custom_value != None:
value = custom_value
b = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)
chooser = gtk.FileChooserDialog(title=_("Open file.."), buttons=b)
if os.path.exists(value):
chooser.set_filename(value)
else:
chooser.set_current_folder(os.environ.get("HOME"))
chooser.set_filter(self.CreateFilter())
ret = chooser.run()
filename = chooser.get_filename()
chooser.destroy()
if ret == gtk.RESPONSE_OK:
if self.CheckFileType(filename):
self.SetFileName(filename)
def SetFileName(self, text):
self.PureVirtual('SetFileName')
class FileStringSetting(StringMatchSetting, FileSetting):
def __init__(self, Setting):
StringMatchSetting.__init__(self, Setting)
FileSetting.__init__(self, Setting)
self.Widget = gtk.HBox()
self.Widget.set_spacing(5)
self.Widget.pack_start(self.Entry, True, True)
self.Widget.pack_start(self.Open, False, False)
def SetFileName(self, filename):
self.Entry.set_text(filename)
self.Changed()
class EnumSetting(Setting):
def _Init(self):
self.Widget = gtk.EventBox()
Tooltips.set_tip(self.Widget, self.Setting.LongDesc)
self.Combo = gtk.combo_box_new_text()
self.Widget.add(self.Combo)
sortedItems = sorted(self.Setting.Info[2].items(), EnumSettingSortCompare)
for name, value in sortedItems:
self.Combo.append_text(name)
self.Combo.connect('changed', self.Changed)
def _Read(self):
self.Combo.set_active(self.Setting.Value)
def _Changed(self):
active = self.Combo.get_active_text()
self.Setting.Value = self.Setting.Info[2][active]
class BoolSetting (Setting):
def _Init (self):
self.Custom = True
self.Widget = gtk.HBox ()
self.CheckButton = gtk.CheckButton ()
label = gtk.Label (self.Setting.ShortDesc)
if self.Setting.Integrated:
label.set_markup ("<span foreground=\"blue\">%s</span>" % \
self.Setting.ShortDesc)
self.align = gtk.Alignment (0, 0.5)
self.align.add (label)
self.buttonAlign = gtk.Alignment (0, 0.5)
self.buttonAlign.set_padding (0, 0, 0, 10)
self.buttonAlign.add (self.CheckButton)
Tooltips.set_tip (self.CheckButton, self.Setting.LongDesc)
self.Widget.pack_start (self.align, True, True)
self.Widget.pack_start (self.buttonAlign, False, False)
self.Widget.pack_start (self.Reset, False, False)
self.CheckButton.connect ('toggled', self.Changed)
def _Read (self):
self.CheckButton.set_active (self.Setting.Value)
def _Changed (self):
self.Setting.Value = self.CheckButton.get_active ()
class IntFloatSetting(Setting):
def _Init(self):
inc = 1
if self.Setting.Type == 'Int':
inc = 1
else:
inc = self.Setting.Info[2]
self.Adj = gtk.Adjustment(self.Setting.Value, self.Setting.Info[0], self.Setting.Info[1], inc, inc*10)
self.Spin = gtk.SpinButton(self.Adj)
Tooltips.set_tip(self.Spin, self.Setting.LongDesc)
if self.Setting.Type == 'Float':
self.Spin.set_digits(4)
self.Scale = gtk.HScale(self.Adj)
Tooltips.set_tip(self.Scale, self.Setting.LongDesc)
self.Scale.props.draw_value = False
self.Scale.connect('button-release-event', self.Changed)
self.Scale.connect('focus-out-event', self.Changed)
self.Spin.connect('activate', self.Changed)
self.Spin.connect('button-release-event', self.Changed)
self.Spin.connect('focus-out-event', self.Changed)
self.Widget = self.Scale
def Attach(self, Table, row):
self.Reset.set_sensitive(not self.Setting.ReadOnly)
self.Scale.set_sensitive(not self.Setting.ReadOnly)
self.Spin.set_sensitive(not self.Setting.ReadOnly)
Table.attach(self.Label, 0, 1, row, row+1, gtk.FILL, TableDef, TableX, TableX)
Table.attach(self.Scale, 1, 2, row, row+1, TableDef, TableDef, TableX, TableX)
Table.attach(self.Spin, 2, 3, row, row+1, gtk.FILL, TableDef, TableX, TableX)
Table.attach(self.Reset, 99, 100, row, row+1, 0, TableDef, TableX, TableX)
def _Read(self):
self.Adj.set_value(self.Setting.Value)
def _Changed(self):
self.Setting.Value = self.Adj.get_value()
class ColorSetting(Setting):
def _Init(self):
self.Widget = gtk.ColorButton()
Tooltips.set_tip(self.Widget, self.Setting.LongDesc)
self.Widget.set_use_alpha(True)
self.Widget.connect('color-set', self.Changed)
def _Read(self):
col = gtk.gdk.Color()
col.red = self.Setting.Value[0]
col.green = self.Setting.Value[1]
col.blue = self.Setting.Value[2]
self.Widget.set_color(col)
self.Widget.set_alpha(self.Setting.Value[3])
def _Changed(self):
col = self.Widget.get_color()
alpha = self.Widget.get_alpha()
self.Setting.Value = [col.red, col.green, col.blue, alpha]
class MultiListSetting(Setting):
def _Init(self):
self.Widget = gtk.VBox()
self.Custom = True
self.Settings = self.Setting # self.Setting is a list in this case
types, cols = self.ListInfo()
self.Types = types
self.Store = gtk.ListStore(*types)
self.View = gtk.TreeView(self.Store)
Tooltips.set_tip(self.View, _("Multi-list settings. You can double-click a row to edit the values."))
self.View.set_headers_visible(True)
for col in cols:
self.View.insert_column_with_attributes(-1, col[0], col[1], **col[2])
self.Store.connect('row-deleted', self.Changed)
self.Store.connect('rows-reordered', self.Changed)
self.View.connect('row-activated', self.Activated)
self.Select = self.View.get_selection()
self.Select.set_mode(gtk.SELECTION_MULTIPLE)
self.Widget.set_border_width(5)
self.Widget.set_spacing(5)
self.Widget.set_size_request(-1, 170)
self.Scroll = gtk.ScrolledWindow()
self.Scroll.props.hscrollbar_policy = gtk.POLICY_NEVER
self.Scroll.props.hscrollbar_policy = gtk.POLICY_AUTOMATIC
self.Scroll.add(self.View)
self.Widget.pack_start(self.Scroll, True, True)
buttonBox = gtk.HBox(False)
buttonBox.set_spacing(5)
self.Widget.pack_start(buttonBox, False, False)
buttonTypes = ((gtk.STOCK_ADD, self.Add),
(gtk.STOCK_DELETE, self.Delete),
(gtk.STOCK_EDIT, self.Edit),
(gtk.STOCK_GO_UP, self.MoveUp),
(gtk.STOCK_GO_DOWN, self.MoveDown),)
for type in buttonTypes:
b = gtk.Button(type[0])
b.set_use_stock(True)
buttonBox.pack_start(b, False, False)
b.connect('clicked', type[1])
buttonBox.pack_end(self.Reset, False, False)
def ColChanged(self, *args, **kwargs):
if self.Blocked <= 0:
self._ColChanged(*args, **kwargs)
self.Settings[0].Plugin.Context.Write()
def Changed(self, *args, **kwargs):
if self.Blocked <= 0:
self._Changed()
self.Settings[0].Plugin.Context.Write()
def DoReset(self, foo):
for setting in self.Settings:
setting.Reset()
self.Setting[0].Plugin.Context.Write()
self.Read()
def MakeLabel(self):
pass
def Add(self, b):
values = []
for setting in self.Settings:
if len(setting.Info) > 0 and setting.Info[0] == 'Int' and len(setting.Info[1][2]) > 0:
sortedItems = sorted(setting.Info[1][2].items(), EnumSettingSortCompare)
# select first item by default
pos = 0
value = sortedItems[pos][0]
elif setting.Info[0] == "Int" or setting.Info[0] == "Float":
value = 0
else:
value = ""
values.append(value)
values = self._Edit(values)
if values is not None:
self.Block()
iter = self.Store.append()
self.UnBlock()
col = 0
for value in values:
self.SetIterValue(iter, col, value)
col += 1
self.Changed()
def Delete(self, b):
selectedRows = self.Select.get_selected_rows()[1]
for path in selectedRows:
iter = self.Store.get_iter(path)
self.Store.remove(iter)
def Edit(self, b):
selectedRows = self.Select.get_selected_rows()[1]
if len(selectedRows) == 1:
iter = self.Store.get_iter(selectedRows[0])
values = []
for col in range(len(self.Settings)):
value = self.Store.get(iter, col)[0]
values.append(value)
values = self._Edit(values)
if values != None:
col = 0
for value in values:
self.SetIterValue(iter, col, value)
col += 1
self.Changed()
def MoveUp(self, b):
selectedRows = self.Select.get_selected_rows()[1]
if len(selectedRows) == 1:
iter = self.Store.get_iter(selectedRows[0])
prev = self.Store.get_iter_first()
if not self.Store.get_path(prev) == self.Store.get_path(iter):
while prev is not None and not self.Store.get_path(self.Store.iter_next(prev)) == self.Store.get_path(iter):
prev = self.Store.iter_next(prev)
self.Store.swap(iter, prev)
def MoveDown(self, b):
selectedRows = self.Select.get_selected_rows()[1]
if len(selectedRows) == 1:
iter = self.Store.get_iter(selectedRows[0])
next = self.Store.iter_next(iter)
if next is not None:
self.Store.swap(iter, next)
def ListInfo(self):
types = []
cols = []
col = 0
for setting in self.Settings:
if setting.Info[0] == "String" or setting.Info[0] == "Match":
types.append(gobject.TYPE_STRING)
elif setting.Info[0] == "Int" and len(setting.Info[1][2]) > 0:
types.append(gobject.TYPE_STRING)
elif setting.Info[0] == "Int":
types.append(gobject.TYPE_INT)
elif setting.Info[0] == "Float":
types.append(gobject.TYPE_FLOAT)
renderer = gtk.CellRendererText()
renderer.connect("edited", self.ColChanged, col)
cols.append((setting.ShortDesc, renderer, {'text':col}))
col += 1
return types, cols
def Activated(self, object, path, col):
self.Edit(None)
def _Read(self):
self.Store.clear()
iters = []
for values in self.Settings[0].Value:
iters.append(self.Store.append())
row = 0
for iter in iters:
for j in range(len(self.Settings)):
setting = self.Settings[j]
value = None
if len(setting.Info) > 0 and setting.Info[0] == 'Int' and len(setting.Info[1][2]) > 0:
pos = setting.Value[row]
sortedItems = sorted(setting.Info[1][2].items(), EnumSettingSortCompare)
value = sortedItems[pos][0]
else:
if row < len(setting.Value):
value = setting.Value[row]
else:
if setting.Info[0] == 'Int':
value = 0
elif setting.Info[0] == 'String' or setting.Info[0] == 'Match':
value = ""
self.Store.set(iter, j, value)
row += 1
def _Edit(self, values=None):
dlg = gtk.Dialog(_("Edit"))
dlg.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
dlg.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK).grab_default()
dlg.set_default_response(gtk.RESPONSE_OK)
table = gtk.Table()
dlg.vbox.pack_start(table)
row = 0
widgets = []
for setting in self.Settings:
ebox = gtk.EventBox()
label = gtk.Label(setting.ShortDesc)
ebox.add(label)
Tooltips.set_tip(ebox, setting.LongDesc)
if self.Types[row] == gobject.TYPE_STRING and setting.Info[0] == 'Int' and len(setting.Info[1][2]) > 0:
comboBox = gtk.combo_box_new_text()
sortedItems = sorted(setting.Info[1][2].items(), EnumSettingSortCompare)
for item in sortedItems:
comboBox.append_text(item[0])
if values != None:
pos = values[row]
value = setting.Info[1][2][pos]
comboBox.set_active(value)
table.attach(ebox, 0, 1, row, row+1, xpadding=5, xoptions=gtk.FILL)
table.attach(comboBox, 2, 3, row, row+1, xpadding=5)
widgets.append(comboBox)
elif self.Types[row] == gobject.TYPE_STRING:
Tooltips.set_tip(ebox, setting.LongDesc)
entry = gtk.Entry()
Tooltips.set_tip(entry, setting.LongDesc)
if values != None:
entry.set_text(values[row])
table.attach(ebox, 0, 1, row, row+1, xpadding=5, xoptions=gtk.FILL)
table.attach(entry, 2, 3, row, row+1, xpadding=5)
widgets.append(entry)
elif self.Types[row] == gobject.TYPE_INT or self.Types[row] == gobject.TYPE_FLOAT:
inc = 0
if setting.Info[0] == 'Int':
inc = 1
else:
inc = setting.Info[1][2]
value = 0
if values != None:
value = values[row]
adjustment = gtk.Adjustment(value, setting.Info[1][0], setting.Info[1][1], inc, inc*10)
spin = gtk.SpinButton(adjustment)
Tooltips.set_tip(spin, setting.LongDesc)
if setting.Info[0] == 'Float':
spin.set_digits(4)
scale = gtk.HScale(adjustment)
Tooltips.set_tip(scale, setting.LongDesc)
scale.props.draw_value = False
table.attach(ebox, 0, 1, row, row+1, xpadding=5, xoptions=gtk.FILL)
table.attach(scale, 2, 3, row, row+1, xpadding=5)
table.attach(spin, 3, 4, row, row+1, xpadding=5, xoptions=gtk.FILL)
widgets.append(adjustment)
row += 1
dlg.vbox.show_all()
ret = dlg.run()
dlg.destroy()
if ret == gtk.RESPONSE_OK:
values = []
row = 0
for type in self.Types:
if type == gobject.TYPE_STRING:
value = None
if widgets[row].__class__ == gtk.Entry:
value = widgets[row].get_text()
elif widgets[row].__class__ == gtk.ComboBox:
value = widgets[row].get_active_text()
values.append(value)
elif type == gobject.TYPE_INT:
value = int(widgets[row].get_value())
values.append(value)
elif type == gobject.TYPE_FLOAT:
value = widgets[row].get_value()
values.append(value)
row += 1
return values
return None
def SetIterValue(self, iter, col, value):
if self.Types[col] == gobject.TYPE_STRING:
self.Store.set(iter, col, value)
elif self.Types[col] == gobject.TYPE_INT:
self.Store.set(iter, col, int(value))
elif self.Types[col] == gobject.TYPE_FLOAT:
self.Store.set(iter, col, float(value))
def _ColChanged(self, obj, path, value, col):
iter = self.Store.get_iter_from_string(path)
self.SetIterValue(iter, col, value)
self._Changed()
def _Changed(self):
col = 0
for setting in self.Settings:
iter = self.Store.get_iter_first()
values = []
while iter:
value = None
if setting.Info[0] == 'Int' and len(setting.Info[1][2]) > 0:
pos = self.Store.get(iter, col)[0]
value = setting.Info[1][2][pos]
else:
value = self.Store.get(iter, col)[0]
values.append(value)
iter = self.Store.iter_next(iter)
setting.Value = values
col += 1
def Attach(self, table, row):
table.attach(self.Widget, 0, 100, row, row+1, xpadding=5)
class ListSetting(Setting):
def _Init(self):
self.Widget = gtk.Frame(self.Setting.ShortDesc)
label = self.Widget.get_label_widget()
if self.Setting.Integrated:
label.set_markup("<span foreground=\"blue\">%s</span>" % self.Setting.ShortDesc)
self.Custom = True
info = self._ListInfo()
self.Store = gtk.ListStore(*info[0])
self.View = gtk.TreeView(self.Store)
Tooltips.set_tip(self.View, self.Setting.LongDesc)
if len(info[0]) == 1:
self.View.set_headers_visible(False)
for i in info[1]:
self.View.insert_column_with_attributes(-1, i[1], i[0], **i[2])
self.Store.connect('row-changed', self.Changed)
self.Store.connect('row-deleted', self.Changed)
self.Store.connect('row-inserted', self.Changed)
self.Store.connect('rows-reordered', self.Changed)
self.View.connect('row-activated', self.Activated)
self.Select = self.View.get_selection()
self.Select.set_mode(gtk.SELECTION_MULTIPLE)
box = gtk.VBox()
box.set_border_width(5)
box.set_spacing(5)
self.Widget.add(box)
self.Scroll = gtk.ScrolledWindow()
self.Scroll.props.hscrollbar_policy = gtk.POLICY_NEVER
self.Scroll.props.hscrollbar_policy = gtk.POLICY_AUTOMATIC
self.Scroll.add(self.View)
box.pack_start(self.Scroll, True, True)
buttonBox = gtk.HBox(False)
buttonBox.set_spacing(5)
box.pack_start(buttonBox, False, False)
buttonTypes = ((gtk.STOCK_ADD, self.Add),
(gtk.STOCK_DELETE, self.Delete),
(gtk.STOCK_EDIT, self.Edit),
(gtk.STOCK_GO_UP, self.MoveUp),
(gtk.STOCK_GO_DOWN, self.MoveDown),)
for type in buttonTypes:
b = gtk.Button(type[0])
b.set_use_stock(True)
buttonBox.pack_start(b, False, False)
b.connect('clicked', type[1])
buttonBox.pack_end(self.Reset, False, False)
def Add(self, b):
value = self._Edit()
if value is not None:
self.Block()
Iter = self.Store.append()
self.UnBlock()
self._ListSet(Iter, value)
def Delete(self, b):
selectedRows = self.Select.get_selected_rows()[1]
for path in selectedRows:
iter = self.Store.get_iter(path)
self.Store.remove(iter)
def Activated(self, object, path, col):
self.Edit(None)
def Edit(self, b):
selectedRows = self.Select.get_selected_rows()[1]
if len(selectedRows) == 1:
iter = self.Store.get_iter(selectedRows[0])
value = self._Edit(self._ListGet(iter))
if value is not None:
self._ListSet(iter, value)
def MoveUp(self, b):
selectedRows = self.Select.get_selected_rows()[1]
if len(selectedRows) == 1:
iter = self.Store.get_iter(selectedRows[0])
prev = self.Store.get_iter_first()
if not self.Store.get_path(prev) == self.Store.get_path(iter):
while prev is not None and not self.Store.get_path(self.Store.iter_next(prev)) == self.Store.get_path(iter):
prev = self.Store.iter_next(prev)
self.Store.swap(iter, prev)
def MoveDown(self, b):
selectedRows = self.Select.get_selected_rows()[1]
if len(selectedRows) == 1:
iter = self.Store.get_iter(selectedRows[0])
next = self.Store.iter_next(iter)
if next is not None:
self.Store.swap(iter, next)
def _ListInfo(self):
self.PureVirtual('_ListInfo')
def _Read(self):
self.Store.clear()
for value in self.Setting.Value:
iter = self.Store.append()
self._ListSet(iter, value)
def _ListSet(self, iter, value):
self.PureVirtual('_ListRead')
def _ListGet(self, iter):
self.PureVirtual('_ListGet')
def _Edit(self, d, value = None):
self.PureVirtual('_Edit')
def _Changed(self):
values = []
iter = self.Store.get_iter_first()
while iter:
value = self._ListGet(iter)
if value != "":
values.append(value)
iter = self.Store.iter_next(iter)
self.Setting.Value = values
def Attach(self, table, row):
self.Widget.set_sensitive(not self.Setting.ReadOnly)
self.Reset.set_sensitive(not self.Setting.ReadOnly)
table.attach(self.Widget, 0, 100, row, row+1, xpadding=5)
class StringMatchListSetting(ListSetting):
def _ListInfo(self):
return (gobject.TYPE_STRING, ), [(gtk.CellRendererText(), _("Value (%s)") % self.Setting.Info[0], {'text':0})]
def _ListSet(self, iter, value):
self.Store.set(iter, 0, value)
def _ListGet(self, iter):
return self.Store.get(iter, 0)[0]
def _Edit(self, value=""):
dlg = gtk.Dialog(_("Edit %s") % self.Setting.ShortDesc)
dlg.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
dlg.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK).grab_default()
dlg.set_default_response(gtk.RESPONSE_OK)
ebox = gtk.EventBox()
label = gtk.Label(_("Value (%s) for %s:") % (self.Setting.Info[0], self.Setting.ShortDesc))
ebox.add(label)
Tooltips.set_tip(ebox, self.Setting.LongDesc)
dlg.vbox.pack_start(ebox)
entry = gtk.Entry()
Tooltips.set_tip(entry, self.Setting.LongDesc)
entry.props.activates_default = True
entry.set_text(value)
dlg.vbox.pack_start(entry)
dlg.vbox.show_all()
ret = dlg.run()
dlg.destroy()
if ret == gtk.RESPONSE_OK:
return entry.get_text()
return None
class FileListSetting(StringMatchListSetting, FileSetting):
def __init__(self, Setting):
StringMatchListSetting.__init__(self, Setting)
FileSetting.__init__(self, Setting)
def _Edit(self, value=""):
dlg = gtk.Dialog(_("Edit %s") % self.Setting.ShortDesc)
dlg.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
dlg.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK).grab_default()
dlg.set_default_response(gtk.RESPONSE_OK)
ebox = gtk.EventBox()
label = gtk.Label(_("Value (%s) for %s:") % (self.Setting.Info[0], self.Setting.ShortDesc))
ebox.add(label)
Tooltips.set_tip(ebox, self.Setting.LongDesc)
dlg.vbox.pack_start(ebox)
hbox = gtk.HBox()
hbox.set_spacing(5)
entry = gtk.Entry()
Tooltips.set_tip(entry, self.Setting.LongDesc)
entry.props.activates_default = True
entry.set_text(value)
hbox.pack_start(entry)
self.Entry = entry
open = gtk.Button()
open.set_image(gtk.image_new_from_stock(gtk.STOCK_OPEN, gtk.ICON_SIZE_BUTTON))
open.connect('clicked', self.OpenFileChooser, value)
hbox.pack_start(open, False, False)
dlg.vbox.pack_start(hbox)
dlg.vbox.show_all()
ret = dlg.run()
dlg.destroy()
self.Entry = None
if ret == gtk.RESPONSE_OK:
return entry.get_text()
return None
def SetFileName(self, filename):
if self.Entry != None:
self.Entry.set_text(filename)
class IntDescListSetting(Setting):
def _Init(self):
self.Widget = gtk.Frame(self.Setting.ShortDesc)
self.Table = gtk.Table()
self.Custom = True
row = 0
col = 0
self.Checks = []
sortedItems = sorted(self.Setting.Info[1][2].items(), EnumSettingSortCompare)
self.minVal = sortedItems[0][1]
for key, value in sortedItems:
box = gtk.CheckButton(key)
Tooltips.set_tip(box, self.Setting.LongDesc)
self.Checks.append((key, box))
self.Table.attach(box, col, col+1, row, row+1, TableDef, TableDef, TableX, TableX)
box.connect('toggled', self.Changed)
col = col+1
if (col >= 3):
col = 0
row = row+1
self.HBox = gtk.HBox()
self.VBox = gtk.VBox()
self.HBox.pack_start(self.VBox, False, False)
self.HBox.pack_start(self.Table, True, True)
self.VBox.pack_start(self.Reset, False, False)
self.Widget.add(self.HBox)
def _Read(self):
for key, box in self.Checks:
box.set_active(False)
for setVal in self.Setting.Value:
self.Checks[setVal-self.minVal][1].set_active(True)
def _Changed(self):
values = []
for key, box in self.Checks:
if box.get_active():
values.append(self.Setting.Info[1][2][key])
self.Setting.Value = values
def Attach(self, table, row):
self.Widget.set_sensitive(not self.Setting.ReadOnly)
self.Reset.set_sensitive(not self.Setting.ReadOnly)
table.attach(self.Widget, 0, 100, row, row+1, xpadding = 5)
class IntFloatListSetting(ListSetting):
def _ListInfo(self):
return (gobject.TYPE_STRING, ), [(gtk.CellRendererText(),
_("Value (%s)") % self.Setting.Info[0], {'text':0})]
def _ListSet(self, Iter, v):
self.Store.set(Iter, 0, str(v))
def _ListGet(self, Iter):
return eval(self.Store.get(Iter, 0)[0])
def _Edit(self, value = None):
dlg = gtk.Dialog(_("Edit %s") % self.Setting.ShortDesc)
dlg.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
dlg.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK).grab_default()
dlg.set_default_response(gtk.RESPONSE_OK)
label = gtk.Label(_("Value (%s) for %s:") % (self.Setting.Info[0], self.Setting.ShortDesc))
ebox = gtk.EventBox()
ebox.add(label)
Tooltips.set_tip(ebox, self.Setting.LongDesc)
dlg.vbox.pack_start(ebox)
box = gtk.HBox()
dlg.vbox.pack_start(box)
val = self.Setting.Info[1][0]
if value is not None:
val = value
if self.Setting.Info[0] == 'Int':
inc = 1
else:
inc = self.Setting.Info[1][2]
adj = gtk.Adjustment(val,
self.Setting.Info[1][0], self.Setting.Info[1][1],
inc, inc*10)
spin = gtk.SpinButton(adj)
Tooltips.set_tip(spin, setting.LongDesc)
if self.Setting.Info[0] == 'Float':
spin.set_digits(4)
scale = gtk.HScale(adj)
Tooltips.set_tip(scale, setting.LongDesc)
scale.props.draw_value = False
box.pack_start(scale, True, True)
box.pack_start(spin, False, False)
dlg.vbox.show_all()
ret = dlg.run()
dlg.destroy()
if ret == gtk.RESPONSE_OK:
return adj.get_value()
return None
def MakeSetting(setting):
if setting.Type == 'String' or setting.Type == 'Match':
if len(setting.Hints) > 0 and setting.Hints.__contains__('file'):
return FileStringSetting(setting)
else:
return StringMatchSetting(setting)
elif setting.Type == 'Bool':
return BoolSetting(setting)
elif setting.Type == 'Int' and len(setting.Info[2].keys()) > 0:
return EnumSetting(setting)
elif setting.Type == 'Float' or setting.Type == 'Int':
return IntFloatSetting(setting)
elif setting.Type == 'Color':
return ColorSetting(setting)
elif setting.Type == 'List':
if setting.Info[0] == 'String' or setting.Info[0] == 'Match':
if len(setting.Hints) > 0 and setting.Hints.__contains__('file'):
return FileListSetting(setting)
else:
return StringMatchListSetting(setting)
elif setting.Info[0] == 'Int':
if len(setting.Info[1][2]) > 0:
return IntDescListSetting(setting)
else:
return IntFloatListSetting(setting)
elif setting.Info[0] == 'Float':
return IntFloatListSetting(setting)
else:
raise TypeError, _("Unhandled list type %s for %s")%(setting.Info[0], setting.Name)
return None
class SubGroupArea:
def __init__(self, name, subGroup, filter=None):
self.MySettings = []
settings = FilterSettings(sorted(sum((v.values() for v in [subGroup.Display]+[subGroup.Screens[CurrentScreenNum]]), []), SettingSortCompare), filter, noActions=True)
if name == '':
self.Widget = gtk.Table()
self.Child = self.Widget
else:
self.Widget = gtk.Frame()
self.Expander = gtk.Expander(name)
self.Widget.add(self.Expander)
self.Expander.set_expanded(False)
self.Child = gtk.Table()
self.Expander.add(self.Child)
# create a special widget for list subGroups
if len(settings) > 1 and HasOnlyType(settings, 'List'):
multiList = MultiListSetting(settings)
multiList.Read()
multiList.Attach(self.Child, 0)
self.Empty = False
self.Expander.set_expanded(True)
return # exit earlier to avoid unneeded logic's
self.Empty = True
row = 0
for setting in settings:
if not setting.Name == 'active_plugins':
set = MakeSetting(setting)
if set is not None:
set.Read()
set.Attach(self.Child, row)
self.MySettings = self.MySettings + [set]
row = row+1
self.Empty = False
if name != '' and row < 4: # ahi hay magic numbers!
self.Expander.set_expanded(True)
syntax highlighted by Code2HTML, v. 0.9.1