quixote/form widget.py,1.39,1.40

Roger Masse <rmasse-fVcApmY9cLvQ3/1i3zOLAti2O/[email protected]> Thu, 07 Nov 2002 13:00:38 -0500
Newsgroups gmane.comp.web.quixote.cvs
Message-ID <[email protected]>
Update of /home/cvs/quixote/form
In directory hewson:/tmp/cvs-serv1994

Modified Files:
	widget.py 
Log Message:
Revised implementation of 'set_options' method for SelectWidget.
In the case where 'key' is not provided in the (options, description, key)
tuple, make 'key' the description (rather than a 'count').  ...This is
to correct the problem of unsorted objects being presented in a different
order or the length of the list changing.  To handle the possibility
of having duplicate descriptions, add an inner function 'unique' that
ensures key uniqueness.


Index: widget.py
===================================================================
RCS file: /home/cvs/quixote/form/widget.py,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- widget.py	7 Nov 2002 17:49:44 -0000	1.39
+++ widget.py	7 Nov 2002 18:00:36 -0000	1.40
@@ -310,28 +310,40 @@
             # provide default values for descriptions and keys
             first = options[0]
             if type(first) is TupleType:
-                if len(first) == 3:
-                    pass
-                elif len(first) == 2:
-                    options = [options[i] + (i,)
-                               for i in range(len(options))]
-                else:
+                if len(first) == 2:
+                    options = [ (object, description, description)
+                                for object, description in options ]
+                elif len(first) != 3:
                     raise ValueError, 'invalid options %r' % options
             else:
-                options = zip(options, options, range(len(options)))
+                options = zip(options, options, options)
 
-        if sort:
-            def compare(a, b):
-                a_value, a_description, a_key = a
-                b_value, b_description, b_key = b
-                if a_value is None:
-                    if b_value is not None:
-                        return -1
-                elif b_value is None:
-                    return 1
-                return cmp(str(a_description).lower(),
-                           str(b_description).lower())
-            options.sort(compare)
+            # Look for duplicate keys.  If any are found, replace them.
+            found = {}
+            
+            def unique (key):
+                count = 1
+                while key in found:
+                    key = "%s__%d__" % (key, count)
+                    count += 1
+                found[key]=1
+                return key
+
+            options = [ (object, description, unique(key))
+                        for object, description, key in options ]
+
+            if sort:
+                def compare(a, b):
+                    a_value, a_description, a_key = a
+                    b_value, b_description, b_key = b
+                    if a_value is None:
+                        if b_value is not None:
+                            return -1
+                    elif b_value is None:
+                        return 1
+                    return cmp(str(a_description).lower(),
+                               str(b_description).lower())
+                options.sort(compare)
         self.options = options
 
     def set_allowed_values (self, allowed_values, descriptions=None, sort=0):