/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/Model/classification.py
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/Thuban/Model/classification.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 436 by jonathan, Thu Feb 27 15:53:03 2003 UTC revision 1426 by jonathan, Wed Jul 16 13:22:20 2003 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001 by Intevation GmbH  # Copyright (c) 2001, 2003 by Intevation GmbH
2  # Authors:  # Authors:
3  # Jonathan Coles <[email protected]>  # Jonathan Coles <[email protected]>
4  #  #
# Line 16  an input value falls with a range that d Line 16  an input value falls with a range that d
16  If no mapping can be found then default data will  If no mapping can be found then default data will
17  be returned. Input values must be hashable objects  be returned. Input values must be hashable objects
18    
19  See the description of GetClassData() for more information  See the description of FindGroup() for more information
20  on the mapping algorithm.  on the mapping algorithm.
21  """  """
22        
23  # fix for people using python2.1  import copy, operator, types
 from __future__ import nested_scopes  
   
 from types import *  
   
 from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \  
      LAYER_VISIBILITY_CHANGED  
24    
25  from Thuban import _  from Thuban import _
 from Thuban.Model.color import Color  
   
 import Thuban.Model.layer  
26    
27  from wxPython.wx import *  from messages import \
28        LAYER_PROJECTION_CHANGED, \
29        LAYER_LEGEND_CHANGED, \
30        LAYER_VISIBILITY_CHANGED,\
31        CLASS_CHANGED
32    
33  # constants  from Thuban.Model.color import Color, Transparent, Black
34  RANGE_MIN  = 0  from Thuban.Model.range import Range
 RANGE_MAX  = 1  
 RANGE_DATA = 2  
35    
36  class Classification:  import Thuban.Model.layer
37    
38      def __init__(self, layer = None, field = None):  from Thuban.Lib.connector import Publisher
         """Initialize a classification.  
39    
40             layer -- the layer object who owns this classification  class Classification(Publisher):
41        """Encapsulates the classification of layer.
42        
43        The Classification divides some kind of data into Groups which
44        are associated with properties. Later the properties can be
45        retrieved by matching data values to the appropriate group.
46        """
47    
48             field -- the name of the data table field that      def __init__(self):
49                      is to be used to classify layer properties          """Initialize a classification."""
         """  
50    
51          self.layer = None # stop message sending          self.__groups = []
52    
53          self.SetDefaultGroup(ClassGroupDefault())          self.SetDefaultGroup(ClassGroupDefault())
         self.SetField(field)  
   
         self.layer = layer  
         self.points = []  
         self.ranges = []  
         self.maps   = []  
54    
55      def __iter__(self):      def __iter__(self):
56          return ClassIterator(self.DefaultGroup,          return ClassIterator(self.__groups)
                              self.points,  
                              self.ranges,  
                              self.maps)  
   
     def __SendMessage(self, message):  
         if self.layer is not None:  
             self.layer.changed(message, self.layer)  
       
     def SetField(self, field):  
         """Set the name of the data table field to use.  
           
            field -- if None then all values map to the default data  
         """  
   
         if field == "":  
             field = None  
57    
58          self.field = field      def __deepcopy__(self, memo):
59          self.__SendMessage(LAYER_LEGEND_CHANGED)          clazz = Classification()
60    
61      def GetField(self):          clazz.__groups[0] = copy.deepcopy(self.__groups[0])
         return self.field  
62    
63      def SetLayer(self, layer):          for i in range(1, len(self.__groups)):
64          assert(isinstance(layer, Thuban.Model.layer.Layer))              clazz.__groups.append(copy.deepcopy(self.__groups[i]))
         self.layer = layer  
         self.__SendMessage(LAYER_LEGEND_CHANGED)  
65    
66      def GetLayer(self):          return clazz
         return layer.self  
   
     def SetDefaultGroup(self, group):  
         """Set the group to be used when a value can't be classified.  
   
            group -- group that the value maps to. See class description.  
         """  
   
         assert(isinstance(group, ClassGroupDefault))  
         self.DefaultGroup = group  
   
     def GetDefaultGroup(self):  
         return self.DefaultGroup  
67    
68        def __SendNotification(self):
69            """Notify the layer that this class has changed."""
70            self.issue(CLASS_CHANGED)
71        
72      #      #
73      # these SetDefault* methods are really only provided for      # these SetDefault* methods are really only provided for
74      # some backward compatibility. they should be considered      # some backward compatibility. they should be considered
# Line 113  class Classification: Line 76  class Classification:
76      #      #
77    
78      def SetDefaultFill(self, fill):      def SetDefaultFill(self, fill):
79          assert(isinstance(fill, Color))          """Set the default fill color.
80          self.DefaultGroup.GetProperties().SetFill(fill)  
81          self.__SendMessage(LAYER_LEGEND_CHANGED)          fill -- a Color object.
82            """
83            self.GetDefaultGroup().GetProperties().SetFill(fill)
84            self.__SendNotification()
85                    
86      def GetDefaultFill(self):      def GetDefaultFill(self):
87          return self.DefaultGroup.GetProperties().GetFill()          """Return the default fill color."""
88            return self.GetDefaultGroup().GetProperties().GetFill()
89                    
90      def SetDefaultStroke(self, stroke):      def SetDefaultLineColor(self, color):
91          assert(isinstance(stroke, Color))          """Set the default line color.
92          self.DefaultGroup.GetProperties().SetStroke(stroke)  
93          self.__SendMessage(LAYER_LEGEND_CHANGED)          color -- a Color object.
94            """
95            self.GetDefaultGroup().GetProperties().SetLineColor(color)
96            self.__SendNotification()
97                    
98      def GetDefaultStroke(self):      def GetDefaultLineColor(self):
99          return self.DefaultGroup.GetProperties().GetStroke()          """Return the default line color."""
100            return self.GetDefaultGroup().GetProperties().GetLineColor()
101                    
102      def SetDefaultStrokeWidth(self, strokeWidth):      def SetDefaultLineWidth(self, lineWidth):
103          assert(isinstance(strokeWidth, IntType))          """Set the default line width.
104          self.DefaultGroup.GetProperties().SetStrokeWidth(strokeWidth)  
105          self.__SendMessage(LAYER_LEGEND_CHANGED)          lineWidth -- an integer > 0.
106            """
107            assert isinstance(lineWidth, types.IntType)
108            self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)
109            self.__SendNotification()
110                    
111      def GetDefaultStrokeWidth(self):      def GetDefaultLineWidth(self):
112          return self.DefaultGroup.GetProperties().GetStrokeWidth()          """Return the default line width."""
113            return self.GetDefaultGroup().GetProperties().GetLineWidth()
114                    
     def AddGroup(self, item):  
         assert(isinstance(item, ClassGroup))  
115    
116          if isinstance(item, ClassGroupDefault):      #
117              self.SetDefaultGroup(item)      # The methods that manipulate self.__groups have to be kept in
118          elif isinstance(item, ClassGroupSingleton):      # sync. We store the default group in index 0 to make it
119              self.points.append(item)      # convienent to iterate over the classification's groups, but
120          elif isinstance(item, ClassGroupRange):      # from the user's perspective the first (non-default) group is
121              self.ranges.append(item)      # at index 0 and the DefaultGroup is a special entity.
122          elif isinstance(item, ClassGroupMap):      #
123              self.maps.append(item)  
124        def SetDefaultGroup(self, group):
125            """Set the group to be used when a value can't be classified.
126    
127            group -- group that the value maps to.
128            """
129    
130            assert isinstance(group, ClassGroupDefault)
131            if len(self.__groups) > 0:
132                self.__groups[0] = group
133          else:          else:
134              raise ValueError(_("Unrecognized ClassGroup"))              self.__groups.append(group)
135    
136        def GetDefaultGroup(self):
137            """Return the default group."""
138            return self.__groups[0]
139    
140        def AppendGroup(self, item):
141            """Append a new ClassGroup item to the classification.
142    
143            item -- this must be a valid ClassGroup object
144            """
145    
146            self.InsertGroup(self.GetNumGroups(), item)
147    
148        def InsertGroup(self, index, group):
149            assert isinstance(group, ClassGroup)
150            self.__groups.insert(index + 1, group)
151            self.__SendNotification()
152    
153          self.__SendMessage(LAYER_LEGEND_CHANGED)      def RemoveGroup(self, index):
154            return self.__groups.pop(index + 1)
155    
156      def GetGroup(self, value):      def ReplaceGroup(self, index, group):
157          """Return the associated data, or the default data.          assert isinstance(group, ClassGroup)
158            self.__groups[index + 1] = group
159            self.__SendNotification()
160    
161             The following search technique is used:      def GetGroup(self, index):
162                 (1) if the field is None, return the default data          return self.__groups[index + 1]
                (2) check if the value exists as a single value  
                (3) check if the value falls within a range. Ranges  
                    are checked in the order they were added to  
                    the classification.  
   
            value -- the value to classify. If there is no mapping,  
                     or value is None, return the default properties  
         """  
   
         if self.field is not None and value is not None:  
   
             for p in self:  
                 if p.Matches(value):  
                     return p  
 #           #  
 #           # check the discrete values  
 #           #  
 #           if self.points.has_key(value):  
 #               return self.points[value]  
 #           #for p in self.points:  
 #               #if p.Value  
   
 #           #  
 #           # check the ranges  
 #           #  
 #           for p in self.ranges:  
 #               if p.InRange(value):  
 #                   return p  
   
 #           #  
 #           # check the maps  
 #           #  
 #           for p in self.maps:  
 #               try:  
 #                   return p.Map(value)  
 #               except: pass  
163    
164          return self.DefaultGroup      def GetNumGroups(self):
165            """Return the number of non-default groups in the classification."""
166            return len(self.__groups) - 1
167    
168        def FindGroup(self, value):
169            """Return the associated group, or the default group.
170    
171            Groups are checked in the order the were added to the
172            Classification.
173    
174            value -- the value to classify. If there is no mapping,
175                     the field is None or value is None,
176                     return the default properties
177            """
178    
179            if value is not None:
180                for i in range(1, len(self.__groups)):
181                    group = self.__groups[i]
182                    if group.Matches(value):
183                        return group
184    
185            return self.GetDefaultGroup()
186    
187      def GetProperties(self, value):      def GetProperties(self, value):
188          return self.GetGroup(value).GetProperties()          """Return the properties associated with the given value.
189          
190            Use this function rather than Classification.FindGroup().GetProperties()
191            since the returned group may be a ClassGroupMap which doesn't support
192            a call to GetProperties().
193            """
194    
195            group = self.FindGroup(value)
196            if isinstance(group, ClassGroupMap):
197                return group.GetPropertiesFromValue(value)
198            else:
199                return group.GetProperties()
200    
201      def TreeInfo(self):      def TreeInfo(self):
202          items = []          items = []
203    
204          def build_color_item(text, color):          def build_color_item(text, color):
205              if color is Color.None:              if color is Transparent:
206                  return ("%s: %s" % (text, _("None")), None)                  return ("%s: %s" % (text, _("None")), None)
207    
208              return ("%s: (%.3f, %.3f, %.3f)" %              return ("%s: (%.3f, %.3f, %.3f)" %
# Line 219  class Classification: Line 218  class Classification:
218    
219              props = group.GetProperties()              props = group.GetProperties()
220              i = []              i = []
221              v = props.GetStroke()              v = props.GetLineColor()
222              i.append(build_color_item(_("Stroke"), v))              i.append(build_color_item(_("Line Color"), v))
223              v = props.GetStrokeWidth()              v = props.GetLineWidth()
224              i.append(_("Stroke Width: %s") % v)              i.append(_("Line Width: %s") % v)
225              v = props.GetFill()              v = props.GetFill()
226              i.append(build_color_item(_("Fill"), v))              i.append(build_color_item(_("Fill"), v))
227              return (label, i)              return (label, i)
228    
229          for p in self:          for p in self:
230              if isinstance(p, ClassGroupDefault):              items.append(build_item(p, p.GetDisplayText()))
                 items.append(build_item(self.DefaultGroup, _("'DEFAULT'")))  
             elif isinstance(p, ClassGroupSingleton):  
                 items.append(build_item(p, str(p.GetValue())))  
             elif isinstance(p, ClassGroupRange):  
                 items.append(build_item(p, "%s - %s" %  
                                            (p.GetMin(), p.GetMax())))  
   
 #       for p in self.points.values():  
 #           items.append(build_item(p, str(p.GetValue())))  
   
 #       for p in self.ranges:  
 #           items.append(build_item(p, "%s - %s" % (p.GetMin(), p.GetMax())))  
231    
232          return (_("Classification"), items)          return (_("Classification"), items)
233    
234  class ClassIterator:  class ClassIterator:
235        """Allows the Groups in a Classifcation to be interated over.
236    
237      def __init__(self, default, points, ranges, maps):      The items are returned in the following order:
238          self.data = [default, points, ranges, maps]          default data, singletons, ranges, maps
239          self.data_iter = iter(self.data)      """
240          self.iter = None  
241        def __init__(self, data): #default, points, ranges, maps):
242            """Constructor.
243    
244            default -- the default group
245    
246            points -- a list of singleton groups
247    
248            ranges -- a list of range groups
249    
250            maps -- a list of map groups
251            """
252    
253            self.data = data
254            self.data_index = 0
255    
256      def __iter__(self):      def __iter__(self):
257          return self          return self
258    
259      def next(self):      def next(self):
260          if self.iter is None:          """Return the next item."""
261              try:  
262                  self.data_item = self.data_iter.next()          if self.data_index >= len(self.data):
263                  self.iter = iter(self.data_item)              raise StopIteration
264              except TypeError:          else:
265                  return self.data_item              d = self.data[self.data_index]
266                self.data_index += 1
267          try:              return d
268              return self.iter.next()          
         except StopIteration:  
             self.iter = None  
             return self.next()  
         
269  class ClassGroupProperties:  class ClassGroupProperties:
270        """Represents the properties of a single Classification Group.
271      
272        These are used when rendering a layer."""
273    
274        def __init__(self, props = None):
275            """Constructor.
276    
277      def __init__(self, prop = None):          props -- a ClassGroupProperties object. The class is copied if
278                     prop is not None. Otherwise, a default set of properties
279                     is created such that: line color = Black, line width = 1,
280                     and fill color = Transparent
281            """
282    
283          if prop is not None:          if props is not None:
284              self.SetStroke(prop.GetStroke())              self.SetProperties(props)
             self.SetStrokeWidth(prop.GetStrokeWidth())  
             self.SetFill(prop.GetFill())  
285          else:          else:
286              self.SetStroke(Color.None)              self.SetLineColor(Black)
287              self.SetStrokeWidth(1)              self.SetLineWidth(1)
288              self.SetFill(Color.None)              self.SetFill(Transparent)
289    
290      def GetStroke(self):      def SetProperties(self, props):
291          return self.stroke          """Set this class's properties to those in class props."""
292    
293      def SetStroke(self, stroke):          assert isinstance(props, ClassGroupProperties)
294          assert(isinstance(stroke, Color))          self.SetLineColor(props.GetLineColor())
295          self.stroke = stroke          self.SetLineWidth(props.GetLineWidth())
296            self.SetFill(props.GetFill())
297      def GetStrokeWidth(self):          
298          return self.stroke_width      def GetLineColor(self):
299            """Return the line color as a Color object."""
300      def SetStrokeWidth(self, stroke_width):          return self.__stroke
301          assert(isinstance(stroke_width, IntType))  
302          if (stroke_width < 1):      def SetLineColor(self, color):
303              raise ValueError(_("stroke_width < 1"))          """Set the line color.
304    
305            color -- the color of the line. This must be a Color object.
306            """
307    
308            self.__stroke = color
309    
310        def GetLineWidth(self):
311            """Return the line width."""
312            return self.__strokeWidth
313    
314        def SetLineWidth(self, lineWidth):
315            """Set the line width.
316    
317          self.stroke_width = stroke_width          lineWidth -- the new line width. This must be > 0.
318            """
319            assert isinstance(lineWidth, types.IntType)
320            if (lineWidth < 1):
321                raise ValueError(_("lineWidth < 1"))
322    
323            self.__strokeWidth = lineWidth
324    
325      def GetFill(self):      def GetFill(self):
326          return self.fill          """Return the fill color as a Color object."""
327            return self.__fill
328    
329      def SetFill(self, fill):      def SetFill(self, fill):
330          assert(isinstance(fill, Color))          """Set the fill color.
331          self.fill = fill  
332            fill -- the color of the fill. This must be a Color object.
333            """
334    
335            self.__fill = fill
336    
337        def __eq__(self, other):
338            """Return true if 'props' has the same attributes as this class"""
339    
340            #
341            # using 'is' over '==' results in a huge performance gain
342            # in the renderer
343            #
344            return isinstance(other, ClassGroupProperties)   \
345                and (self.__stroke is other.__stroke or      \
346                     self.__stroke == other.__stroke)        \
347                and (self.__fill is other.__fill or          \
348                     self.__fill == other.__fill)            \
349                and self.__strokeWidth == other.__strokeWidth
350    
351        def __ne__(self, other):
352            return not self.__eq__(other)
353    
354        def __copy__(self):
355            return ClassGroupProperties(self)
356    
357        def __deepcopy__(self):
358            return ClassGroupProperties(self)
359    
360        def __repr__(self):
361            return repr((self.__stroke, self.__strokeWidth, self.__fill))
362    
363  class ClassGroup:  class ClassGroup:
364        """A base class for all Groups within a Classification"""
365    
366      def __init__(self, label = ""):      def __init__(self, label = "", props = None, group = None):
367          self.label = label          """Constructor.
368    
369            label -- A string representing the Group's label
370            """
371    
372            if group is not None:
373                self.SetLabel(copy.copy(group.GetLabel()))
374                self.SetProperties(copy.copy(group.GetProperties()))
375                self.SetVisible(group.IsVisible())
376            else:
377                self.SetLabel(label)
378                self.SetProperties(props)
379                self.SetVisible(True)
380    
381      def GetLabel(self):      def GetLabel(self):
382            """Return the Group's label."""
383          return self.label          return self.label
384    
385      def SetLabel(self, label):      def SetLabel(self, label):
386            """Set the Group's label.
387    
388            label -- a string representing the Group's label. This must
389                     not be None.
390            """
391            assert isinstance(label, types.StringTypes)
392          self.label = label          self.label = label
393    
394        def GetDisplayText(self):
395            assert False, "GetDisplay must be overridden by subclass!"
396            return ""
397    
398      def Matches(self, value):      def Matches(self, value):
399          """This needs to be implemented by all subclasses."""          """Determines if this Group is associated with the given value.
         pass  
400    
401      def GetProperties(self, value):          Returns False. This needs to be overridden by all subclasses.
402          """This needs to be implemented by all subclasses."""          """
403          pass          assert False, "GetMatches must be overridden by subclass!"
404            return False
405    
406        def GetProperties(self):
407            """Return the properties associated with the given value."""
408    
409            return self.prop
410    
411        def SetProperties(self, prop):
412            """Set the properties associated with this Group.
413    
414            prop -- a ClassGroupProperties object. if prop is None,
415                    a default set of properties is created.
416            """
417    
418            if prop is None: prop = ClassGroupProperties()
419            assert isinstance(prop, ClassGroupProperties)
420            self.prop = prop
421    
422        def IsVisible(self):
423            return self.visible
424    
425        def SetVisible(self, visible):
426            self.visible = visible
427    
428        def __eq__(self, other):
429            return isinstance(other, ClassGroup) \
430                and self.label == other.label \
431                and self.GetProperties() == other.GetProperties()
432    
433        def __ne__(self, other):
434            return not self.__eq__(other)
435    
436        def __repr__(self):
437            return repr(self.label) + ", " + repr(self.GetProperties())
438            
439  class ClassGroupSingleton(ClassGroup):  class ClassGroupSingleton(ClassGroup):
440        """A Group that is associated with a single value."""
441    
442      def __init__(self, value = 0, prop = None, label = ""):      def __init__(self, value = 0, props = None, label = "", group = None):
443          ClassGroup.__init__(self, label)          """Constructor.
444    
445            value -- the associated value.
446    
447            prop -- a ClassGroupProperites object. If prop is None a default
448                     set of properties is created.
449    
450            label -- a label for this group.
451            """
452            ClassGroup.__init__(self, label, props, group)
453    
454          self.SetValue(value)          self.SetValue(value)
         self.SetProperties(prop)  
455    
456      def __copy__(self):      def __copy__(self):
457          return ClassGroupSingleton(self.value, self.prop, self.label)          return ClassGroupSingleton(self.GetValue(),
458                                       self.GetProperties(),
459                                       self.GetLabel())
460    
461        def __deepcopy__(self, memo):
462            return ClassGroupSingleton(self.GetValue(), group = self)
463    
464      def GetValue(self):      def GetValue(self):
465          return self.value          """Return the associated value."""
466            return self.__value
467    
468      def SetValue(self, value):      def SetValue(self, value):
469          self.value = value          """Associate this Group with the given value."""
470            self.__value = value
471    
472      def Matches(self, value):      def Matches(self, value):
473          return self.value == value          """Determine if the given value matches the associated Group value."""
474    
475      def GetProperties(self, value = None):          """Returns True if the value matches, False otherwise."""
         if value is None: return self.prop  
476    
477          if self.Matches(value):          return self.__value == value
             return self.prop  
         else:  
             return None  
478    
479      def SetProperties(self, prop):      def GetDisplayText(self):
480          if prop is None: prop = ClassGroupProperties()          label = self.GetLabel()
481          assert(isinstance(prop, ClassGroupProperties))  
482          self.prop = prop          if label != "": return label
483    
484            return str(self.GetValue())
485    
486        def __eq__(self, other):
487            return ClassGroup.__eq__(self, other) \
488                and isinstance(other, ClassGroupSingleton) \
489                and self.__value == other.__value
490    
491        def __repr__(self):
492            return "(" + repr(self.__value) + ", " + ClassGroup.__repr__(self) + ")"
493    
494    class ClassGroupDefault(ClassGroup):
495        """The default Group. When values do not match any other
496           Group within a Classification, the properties from this
497           class are used."""
498    
499  class ClassGroupDefault(ClassGroupSingleton):      def __init__(self, props = None, label = "", group = None):
500      def __init__(self, prop = None, label = ""):          """Constructor.
501          ClassGroupSingleton.__init__(self, 0, prop, label)  
502            prop -- a ClassGroupProperites object. If prop is None a default
503                     set of properties is created.
504    
505            label -- a label for this group.
506            """
507    
508            ClassGroup.__init__(self, label, props, group)
509    
510      def __copy__(self):      def __copy__(self):
511          return ClassGroupDefault(self.prop, self.label)          return ClassGroupDefault(self.GetProperties(), self.GetLabel())
512    
513      def GetProperties(self, value = None):      def __deepcopy__(self, memo):
514          return self.prop          return ClassGroupDefault(label = self.GetLabel(), group = self)
515    
516        def Matches(self, value):
517            return True
518    
519        def GetDisplayText(self):
520            label = self.GetLabel()
521    
522            if label != "": return label
523    
524            return _("DEFAULT")
525    
526        def __eq__(self, other):
527            return ClassGroup.__eq__(self, other) \
528                and isinstance(other, ClassGroupDefault) \
529                and self.GetProperties() == other.GetProperties()
530    
531        def __repr__(self):
532            return "(" + ClassGroup.__repr__(self) + ")"
533    
534  class ClassGroupRange(ClassGroup):  class ClassGroupRange(ClassGroup):
535        """A Group that represents a range of values that map to the same
536           set of properties."""
537    
538      def __init__(self, min = 0, max = 1, prop = None, label = ""):      def __init__(self, _range = (0,1), props = None, label = "", group=None):
539          ClassGroup.__init__(self, label)          """Constructor.
540    
541            The minumum value must be strictly less than the maximum.
542    
543            _range -- either a tuple (min, max) where min < max or
544                      a Range object
545    
546          self.SetRange(min, max)          prop -- a ClassGroupProperites object. If prop is None a default
547          self.SetProperties(prop)                   set of properties is created.
548    
549            label -- a label for this group.
550            """
551    
552            ClassGroup.__init__(self, label, props, group)
553            self.SetRange(_range)
554    
555      def __copy__(self):      def __copy__(self):
556          return ClassGroupRange(self.min, self.max, self.prop, self.label)          return ClassGroupRange(self.__range,
557                                   props = self.GetProperties(),
558                                   label = self.GetLabel())
559    
560        def __deepcopy__(self, memo):
561            return ClassGroupRange(copy.copy(self.__range),
562                                   group = self)
563    
564      def GetMin(self):      def GetMin(self):
565          return self.min          """Return the range's minimum value."""
566            return self.__range.GetRange()[1]
567    
568      def SetMin(self, min):      def SetMin(self, min):
569          self.SetRange(min, self.max)          """Set the range's minimum value.
570        
571            min -- the new minimum. Note that this must be less than the current
572                   maximum value. Use SetRange() to change both min and max values.
573            """
574        
575            self.SetRange((min, self.__range.GetRange()[2]))
576    
577      def GetMax(self):      def GetMax(self):
578          return self.max          """Return the range's maximum value."""
579            return self.__range.GetRange()[2]
580    
581      def SetMax(self, max):      def SetMax(self, max):
582          self.SetRange(self.min, max)          """Set the range's maximum value.
583        
584            max -- the new maximum. Note that this must be greater than the current
585                   minimum value. Use SetRange() to change both min and max values.
586            """
587            self.SetRange((self.__range.GetRange()[1], max))
588    
589      def SetRange(self, min, max):      def SetRange(self, _range):
590          if min >= max:          """Set a new range.
591              raise ValueError(_("ClassGroupRange: %i(min) >= %i(max)!") %  
592                               (min, max))          _range -- Either a tuple (min, max) where min < max or
593          self.min = min                    a Range object.
594          self.max = max  
595            Raises ValueError on error.
596            """
597    
598            if isinstance(_range, Range):
599                self.__range = _range
600            elif isinstance(_range, types.TupleType) and len(_range) == 2:
601                self.__range = Range(("[", _range[0], _range[1], "["))
602            else:
603                raise ValueError()
604    
605      def GetRange(self):      def GetRange(self):
606          return (self.min, self.max)          """Return the range as a string"""
607            return self.__range.string(self.__range.GetRange())
608    
609      def Matches(self, value):      def Matches(self, value):
610          return self.min <= value < self.max          """Determine if the given value lies with the current range.
611    
612      def GetProperties(self, value):          The following check is used: min <= value < max.
613          if value is None: return self.prop          """
614    
615          if self.Matches(value):          return operator.contains(self.__range, value)
             return self.prop  
         else:  
             return None  
616    
617      def SetProperties(self, prop):      def GetDisplayText(self):
618          if prop is None: prop = ClassGroupProperties()          label = self.GetLabel()
619          assert(isinstance(prop, ClassGroupProperties))  
620          self.prop = prop          if label != "": return label
621    
622            return self.__range.string(self.__range.GetRange())
623    
624        def __eq__(self, other):
625            return ClassGroup.__eq__(self, other) \
626                and isinstance(other, ClassGroupRange) \
627                and self.__range == other.__range
628    
629        def __repr__(self):
630            return "(" + str(self.__range) + ClassGroup.__repr__(self) + ")"
631    
632  class ClassGroupMap(ClassGroup):  class ClassGroupMap(ClassGroup):
633        """Currently, this class is not used."""
634    
635      FUNC_ID = "id"      FUNC_ID = "id"
636    
637      def __init__(self, map_type = FUNC_ID, func = None, prop = None, label=""):      def __init__(self, map_type = FUNC_ID, func = None, prop = None, label=""):
638          ClassGroup.__init__(self, prop)          ClassGroup.__init__(self, label)
639    
640          self.map_type = map_type          self.map_type = map_type
641          self.func = func          self.func = func
# Line 435  class ClassGroupMap(ClassGroup): Line 646  class ClassGroupMap(ClassGroup):
646      def Map(self, value):      def Map(self, value):
647          return self.func(value)          return self.func(value)
648    
649        def GetProperties(self):
650            return None
651    
652        def GetPropertiesFromValue(self, value):
653            pass
654    
655        def GetDisplayText(self):
656            return "Map: " + self.map_type
657    
658      #      #
659      # built-in mappings      # built-in mappings
660      #      #

Legend:
Removed from v.436  
changed lines
  Added in v.1426

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26