+ nchoices = len(self.choices)
+ i = self.choices.index(self.value)
+ if key == KEY_LEFT:
+ self.value = self.choices[(i + nchoices - 1) % nchoices]
+ elif key == KEY_RIGHT:
+ self.value = self.choices[(i + 1) % nchoices]
+
+ def getText(self):
+ descr = self.description[self.value]
+ if len(descr):
+ return _(descr)
+ return descr
+
+ def getMulti(self, selected):
+ descr = self.description[self.value]
+ if len(descr):
+ return ("text", _(descr))
+ return ("text", descr)
+
+ # HTML
+ def getHTML(self, id):
+ res = ""
+ for v in self.choices:
+ if self.value == v:
+ checked = 'checked="checked" '
+ else:
+ checked = ''
+ res += '<input type="radio" name="' + id + '" ' + checked + 'value="' + v + '">' + self.description[v] + "</input></br>\n"
+ return res;
+
+ def unsafeAssign(self, value):
+ # setValue does check if value is in choices. This is safe enough.
+ self.value = value
+
+# a binary decision.
+#
+# several customized versions exist for different
+# descriptions.
+#
+class ConfigBoolean(ConfigElement):
+ def __init__(self, default = False, descriptions = {False: "false", True: "true"}):
+ ConfigElement.__init__(self)
+ self.descriptions = descriptions
+ self.value = self.default = default
+ def handleKey(self, key):
+ if key in [KEY_LEFT, KEY_RIGHT]:
+ self.value = not self.value
+
+ def getText(self):
+ descr = self.descriptions[self.value]
+ if len(descr):
+ return _(descr)
+ return descr
+
+ def getMulti(self, selected):
+ descr = self.descriptions[self.value]
+ if len(descr):
+ return ("text", _(descr))
+ return ("text", descr)
+
+ def tostring(self, value):
+ if not value:
+ return "false"
+ else:
+ return "true"
+
+ def fromstring(self, val):
+ if val == "true":
+ return True
+ else:
+ return False
+
+ def getHTML(self, id):
+ if self.value:
+ checked = ' checked="checked"'
+ else:
+ checked = ''
+ return '<input type="checkbox" name="' + id + '" value="1" ' + checked + " />"
+
+ # this is FLAWED. and must be fixed.
+ def unsafeAssign(self, value):
+ if value == "1":
+ self.value = True
+ else:
+ self.value = False
+
+class ConfigYesNo(ConfigBoolean):
+ def __init__(self, default = False):
+ ConfigBoolean.__init__(self, default = default, descriptions = {False: _("no"), True: _("yes")})
+
+class ConfigOnOff(ConfigBoolean):
+ def __init__(self, default = False):
+ ConfigBoolean.__init__(self, default = default, descriptions = {False: _("off"), True: _("on")})
+
+class ConfigEnableDisable(ConfigBoolean):
+ def __init__(self, default = False):
+ ConfigBoolean.__init__(self, default = default, descriptions = {False: _("disable"), True: _("enable")})
+
+class ConfigDateTime(ConfigElement):
+ def __init__(self, default, formatstring, increment = 86400):
+ ConfigElement.__init__(self)
+ self.increment = increment
+ self.formatstring = formatstring
+ self.value = self.default = int(default)
+
+ def handleKey(self, key):
+ if key == KEY_LEFT:
+ self.value = self.value - self.increment
+ if key == KEY_RIGHT:
+ self.value = self.value + self.increment
+
+ def getText(self):
+ return time.strftime(self.formatstring, time.localtime(self.value))
+
+ def getMulti(self, selected):
+ return ("text", time.strftime(self.formatstring, time.localtime(self.value)))
+
+ def fromstring(self, val):
+ return int(val)
+
+# *THE* mighty config element class
+#
+# allows you to store/edit a sequence of values.
+# can be used for IP-addresses, dates, plain integers, ...
+# several helper exist to ease this up a bit.
+#
+class ConfigSequence(ConfigElement):
+ def __init__(self, seperator, limits, censor_char = "", default = None):
+ ConfigElement.__init__(self)
+ assert isinstance(limits, list) and len(limits[0]) == 2, "limits must be [(min, max),...]-tuple-list"
+ assert censor_char == "" or len(censor_char) == 1, "censor char must be a single char (or \"\")"
+ #assert isinstance(default, list), "default must be a list"
+ #assert isinstance(default[0], int), "list must contain numbers"
+ #assert len(default) == len(limits), "length must match"
+
+ self.marked_pos = 0
+ self.seperator = seperator
+ self.limits = limits
+ self.censor_char = censor_char
+
+ self.default = default
+ self.value = copy.copy(default)
+
+ def validate(self):
+ max_pos = 0
+ num = 0
+ for i in self._value:
+ max_pos += len(str(self.limits[num][1]))
+
+ while self._value[num] < self.limits[num][0]:
+ self._value[num] += 1
+
+ while self._value[num] > self.limits[num][1]:
+ self._value[num] -= 1
+
+ num += 1
+
+ if self.marked_pos >= max_pos:
+ self.marked_pos = max_pos - 1
+
+ if self.marked_pos < 0:
+ self.marked_pos = 0
+
+ def validatePos(self):
+ if self.marked_pos < 0:
+ self.marked_pos = 0
+
+ total_len = sum([len(str(x[1])) for x in self.limits])
+
+ if self.marked_pos >= total_len:
+ self.marked_pos = total_len - 1
+
+ def handleKey(self, key):
+ if key == KEY_LEFT:
+ self.marked_pos -= 1
+ self.validatePos()
+
+ if key == KEY_RIGHT:
+ self.marked_pos += 1
+ self.validatePos()
+
+ if key in KEY_NUMBERS:
+ block_len = []
+ for x in self.limits:
+ block_len.append(len(str(x[1])))
+
+ total_len = sum(block_len)
+
+ pos = 0
+ blocknumber = 0
+ block_len_total = [0, ]
+ for x in block_len:
+ pos += block_len[blocknumber]
+ block_len_total.append(pos)
+ if pos - 1 >= self.marked_pos:
+ pass
+ else:
+ blocknumber += 1
+
+ number = getKeyNumber(key)