diff urwid_satext/sat_widgets.py @ 68:5c28bb50ae0d

new ListOption class which work like unicode, but make the difference between value and label, so the displayed text can be different from the actual value.
author Goffi <goffi@goffi.org>
date Tue, 24 Dec 2013 15:01:09 +0100
parents c270867a80f9
children b39c81cdd863
line wrap: on
line diff
--- a/urwid_satext/sat_widgets.py	Sat Dec 21 16:55:52 2013 +0100
+++ b/urwid_satext/sat_widgets.py	Tue Dec 24 15:01:09 2013 +0100
@@ -113,7 +113,7 @@
 
 class ModalEdit(AdvancedEdit):
     """AdvancedEdit with vi-like mode management
-    - there is a new 'mode' property wich can be changed with properties
+    - there is a new 'mode' property which can be changed with properties
     specified during init
     - completion callback received a new 'mode' argument
     """
@@ -200,6 +200,8 @@
 
     def __valid_text(self, text):
         """Tmp method needed until dbus and urwid are more friends"""
+        if isinstance(text, ListOption):
+            return text
         if isinstance(text,basestring):
             return unicode(text)
         elif isinstance(text,tuple):
@@ -341,6 +343,66 @@
         self.label = label
         self.set_text([self.left_border, label, self.right_border])
 
+class ListOption(unicode):
+    """ Class similar to unicode, but which make the difference between value and label
+    label is show when use as unicode, the .value attribute contain the actual value
+    Can be initialised with:
+        - basestring (label = value = given string)
+        - a tuple with (value, label)
+    XXX: comparaison is made again value, not the label which is the one displayed
+
+    """
+
+    def __new__(cls, option):
+        if (isinstance(option, cls)):
+            return option
+        elif isinstance(option, basestring):
+            value = label = option
+        elif (isinstance(option, tuple) and len(option) == 2):
+            value, label = option
+        else:
+            raise NotImplementedError
+        if not value:
+            raise ValueError("value can't be empty")
+        if not label:
+            label = value
+        instance = super(ListOption, cls).__new__(cls, label)
+        instance._value = value
+        return instance
+
+    def __eq__(self, other):
+        # XXX: try to compare values, if other has no value
+        #      (e.g. unicode string) try to compare to other itself
+        try:
+            return self._value == other._value
+        except AttributeError:
+            return self._value == other
+
+    def __ne__(self, other):
+        # XXX: see __eq__
+        try:
+            return self._value != other._value
+        except AttributeError:
+            return self._value != other
+
+    @property
+    def value(self):
+        """ return option value """
+        return self._value
+
+    @value.setter
+    def value(self, value):
+        self._value = value
+
+    @staticmethod
+    def fromOptions(options):
+        """ convert a list of string/tuple options to a list of listOption
+        @param options: list of managed option type (basestring, tuple)
+        return: list of ListOption
+        """
+        return [(ListOption(option)) for option in options]
+
+
 class GenericList(urwid.WidgetWrap):
     signals = ['click','change']
 
@@ -424,7 +486,8 @@
         return self.list_box
 
     def changeValues(self, new_values):
-        """Change all value in one shot"""
+        """Change all values in one shot"""
+        new_values = ListOption.fromOptions(new_values)
         if not self.first_display:
             old_selected = self.getSelectedValues()
         widgets = []