/[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 397 by jonathan, Tue Feb 11 14:23:32 2003 UTC revision 544 by jonathan, Thu Mar 20 09:43:48 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 getProperties() for more information  See the description of GetGroup() for more information
20  on the mapping algorithm.  on the mapping algorithm.
21  """  """
22        
23  # fix for people using python2.1  # fix for people using python2.1
24  from __future__ import nested_scopes  from __future__ import nested_scopes
25    
26    import copy
27    
28    from types import *
29    
30  from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \  from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \
31       LAYER_VISIBILITY_CHANGED       LAYER_VISIBILITY_CHANGED
32    
33  from Thuban import _  from Thuban import _
34  from Thuban.Model.color import Color  from Thuban.Model.color import Color
35    
36  from wxPython.wx import *  import Thuban.Model.layer
37    
38  # constants  # constants
39  RANGE_MIN  = 0  RANGE_MIN  = 0
# Line 37  RANGE_MAX  = 1 Line 41  RANGE_MAX  = 1
41  RANGE_DATA = 2  RANGE_DATA = 2
42    
43  class Classification:  class Classification:
44        """Encapsulates the classification of layer. The Classification
45        divides some kind of data into Groups which are associated with
46        properties. Later the properties can be retrieved by matching
47        data values to the appropriate group."""
48    
49      def __init__(self, layer, field = None):      def __init__(self, layer = None, field = None):
50          """Initialize a classification.          """Initialize a classification.
51    
52             layer -- the layer object who owns this classification             layer -- the Layer object who owns this classification
53    
54             field -- the name of the data table field that             field -- the name of the data table field that
55                      is to be used to classify layer properties                      is to be used to classify layer properties
56          """          """
57    
58          self.layer = layer          self.layer = None
59          self.points = {}          self.field = None
60          self.ranges = []          self.fieldType = None
61          self.DefaultData = ClassData()          self.groups = []
62          self.field = field  
63          #self.SetField(field)          self.__setLayerLock = False
64    
65            self.SetDefaultGroup(ClassGroupDefault())
66    
67            self.SetLayer(layer)
68            self.SetField(field)
69    
70        def __iter__(self):
71            return ClassIterator(self.groups)
72    
73        def __SendNotification(self):
74            """Notify the layer that this class has changed."""
75            if self.layer is not None:
76                self.layer.ClassChanged()
77        
78      def SetField(self, field):      def SetField(self, field):
79          """Set the name of the data table field to use.          """Set the name of the data table field to use.
80                    
81               If there is no layer then the field type is set to None,
82               otherwise the layer is queried to find the type of the
83               field data
84    
85             field -- if None then all values map to the default data             field -- if None then all values map to the default data
86          """          """
87    
88            if field == "":
89                field = None
90    
91    
92            if field is None:
93                if self.layer is not None:
94                    self.fieldType = None
95            else:
96                if self.layer is not None:
97                    fieldType = self.layer.GetFieldType(field)
98                    if fieldType is None:
99                        raise ValueError("'%s' was not found in the layer's table."
100                                         % self.field)
101    
102                    #
103                    # unfortunately we cannot call SetFieldType() because it
104                    # requires the layer to be None
105                    #
106                    self.fieldType = fieldType
107                    #self.SetFieldType(fieldType)
108    
109          self.field = field          self.field = field
110          self.layer.changed(LAYER_LEGEND_CHANGED, self.layer)  
111            self.__SendNotification()
112    
113      def GetField(self):      def GetField(self):
114            """Return the name of the field."""
115          return self.field          return self.field
116    
117      def SetDefaultData(self, data):      def GetFieldType(self):
118          """Set the data to be used when a value can't be classified.          """Return the field type."""
119            return self.fieldType
120    
121        def SetFieldType(self, type):
122            """Set the type of the field used by this classification.
123    
124            A ValueError is raised if the owning layer is not None and
125            'type' is different from the current field type.
126            """
127    
128            if type != self.fieldType:
129                if self.layer is not None:
130                    raise ValueError()
131                else:
132                    self.fieldType = type
133                    self.__SendNotification()
134    
135        def SetLayer(self, layer):
136            """Set the owning Layer of this classification.
137    
138               A ValueError exception will be thrown either the field or
139               field type mismatch the information in the layer's table.
140            """
141    
142            # prevent infinite recursion when calling SetClassification()
143            if self.__setLayerLock: return
144    
145            self.__setLayerLock = True
146    
147             data -- data that the value maps to. See class description.          if layer is None:
148                if self.layer is not None:
149                    l = self.layer
150                    self.layer = None
151                    l.SetClassification(None)
152            else:
153                assert(isinstance(layer, Thuban.Model.layer.Layer))
154    
155                old_layer = self.layer
156    
157                self.layer = layer
158    
159                try:
160                    self.SetField(self.GetField()) # this sync's the fieldType
161                except ValueError:
162                    self.layer = old_layer
163                    self.__setLayerLock = False
164                    raise ValueError
165                else:
166                    self.layer.SetClassification(self)
167    
168            self.__setLayerLock = False
169    
170        def GetLayer(self):
171            """Return the parent layer."""
172            return self.layer
173    
174        def SetDefaultGroup(self, group):
175            """Set the group to be used when a value can't be classified.
176    
177               group -- group that the value maps to.
178          """          """
179    
180          self.DefaultData = data          assert(isinstance(group, ClassGroupDefault))
181            self.AddGroup(group)
182    
183      def GetDefaultData(self):      def GetDefaultGroup(self):
184          return self.DefaultData          """Return the default group."""
185            return self.groups[0]
186    
187        #
188        # these SetDefault* methods are really only provided for
189        # some backward compatibility. they should be considered
190        # for removal once all the classification code is finished.
191        #
192    
193      def SetDefaultFill(self, fill):      def SetDefaultFill(self, fill):
194          self.DefaultData.SetFill(fill)          """Set the default fill color.
195          self.layer.changed(LAYER_LEGEND_CHANGED, self.layer)  
196            fill -- a Color object.
197            """
198            assert(isinstance(fill, Color))
199            self.GetDefaultGroup().GetProperties().SetFill(fill)
200            self.__SendNotification()
201                    
202      def GetDefaultFill(self):      def GetDefaultFill(self):
203          return self.DefaultData.GetFill()          """Return the default fill color."""
204            return self.GetDefaultGroup().GetProperties().GetFill()
205                    
206      def SetDefaultStroke(self, stroke):      def SetDefaultLineColor(self, color):
207          self.DefaultData.SetStroke(stroke)          """Set the default line color.
208          self.layer.changed(LAYER_LEGEND_CHANGED, self.layer)  
209            color -- a Color object.
210            """
211            assert(isinstance(color, Color))
212            self.GetDefaultGroup().GetProperties().SetLineColor(color)
213            self.__SendNotification()
214                    
215      def GetDefaultStroke(self):      def GetDefaultLineColor(self):
216          return self.DefaultData.GetStroke()          """Return the default line color."""
217            return self.GetDefaultGroup().GetProperties().GetLineColor()
218                    
219      def SetDefaultStrokeWidth(self, strokeWidth):      def SetDefaultLineWidth(self, lineWidth):
220          self.DefaultData.SetStrokeWidth(strokeWidth)          """Set the default line width.
221          self.layer.changed(LAYER_LEGEND_CHANGED, self.layer)  
222            lineWidth -- an integer > 0.
223            """
224            assert(isinstance(lineWidth, IntType))
225            self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)
226            self.__SendNotification()
227                    
228      def GetDefaultStrokeWidth(self):      def GetDefaultLineWidth(self):
229          return self.DefaultData.GetStrokeWidth()          """Return the default line width."""
230            return self.GetDefaultGroup().GetProperties().GetLineWidth()
231                    
232      def AddRange(self, min, max, data):      def AddGroup(self, item):
233          """Add a new range to the classification.          """Add a new ClassGroup item to the classification.
   
            A range allows a value to be classified if it falls between  
            min and max. Specifically, min <= value < max  
           
            min -- the lower bound.  
   
            max -- the upper bound.  
234    
235             data -- data that the value maps to. See class description.          item -- this must be a valid ClassGroup object
236          """          """
237    
238          if min >= max:          assert(isinstance(item, ClassGroup))
             raise ValueError(_("Range minimum >= maximum!"))  
         self.ranges.append([min, max, data])  
         self.layer.changed(LAYER_LEGEND_CHANGED, self.layer)  
   
     def AddPoint(self, value, data):  
         """Associate a single value with data.  
   
            When this value is to be classified data will be returned.  
239    
240             value -- classification value.          if len(self.groups) > 0 and isinstance(item, ClassGroupDefault):
241                self.groups[0] = item
242            else:
243                self.groups.append(item)
244    
245             data  -- data that the value maps to. See class description.          self.__SendNotification()
         """  
   
         self.points[value] = data  
         self.layer.changed(LAYER_LEGEND_CHANGED, self.layer)  
246    
247      def GetProperties(self, value):      def GetGroup(self, value):
248          """Return the associated data, or the default data.          """Return the associated group, or the default group.
249    
250             The following search technique is used:             Groups are checked in the order the were added to the
251                 (1) if the field is None, return the default data             Classification.
                (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.  
252    
253             value -- the value to classify. If there is no mapping,             value -- the value to classify. If there is no mapping,
254                      or value is None, return the default data                      the field is None or value is None,
255                      (which may be None)                      return the default properties
256          """          """
257    
258          if self.field is not None and value is not None:          if self.GetField() is not None and value is not None:
             #  
             # first check the discrete values  
             #  
             if self.points.has_key(value):  
                 return self.points[value]  
   
             #  
             # now check the ranges  
             #  
             for p in self.ranges:  
                 if (p[RANGE_MIN] <= value) and (value < p[RANGE_MAX]):  
                     return p[RANGE_DATA]  
259    
260                for i in range(1, len(self.groups)):
261                    group = self.groups[i]
262                    if group.Matches(value):
263                        return group
264    
265          return self.DefaultData          return self.GetDefaultGroup()
266    
267        def GetProperties(self, value):
268            """Return the properties associated with the given value."""
269    
270            group = self.GetGroup(value)
271            if isinstance(group, ClassGroupMap):
272                return group.GetPropertiesFromValue(value)
273            else:
274                return group.GetProperties()
275    
276      def TreeInfo(self):      def TreeInfo(self):
277          items = []          items = []
278    
279          #          def build_color_item(text, color):
280          # XXX: shouldn't print anything if there are no classifications              if color is Color.None:
281          #                  return ("%s: %s" % (text, _("None")), None)
282    
283                        return ("%s: (%.3f, %.3f, %.3f)" %
284          def color_string(color):                      (text, color.red, color.green, color.blue),
285              if color is None:                      color)
286                  return "None"  
287              return "(%.3f, %.3f, %.3f)" % (color.red, color.green, color.blue)          def build_item(group, string):
288                label = group.GetLabel()
289                if label == "":
290                    label = string
291                else:
292                    label += " (%s)" % string
293    
294          def build_item(data):              props = group.GetProperties()
295              i = []              i = []
296                v = props.GetLineColor()
297                i.append(build_color_item(_("Line Color"), v))
298                v = props.GetLineWidth()
299                i.append(_("Line Width: %s") % v)
300                v = props.GetFill()
301                i.append(build_color_item(_("Fill"), v))
302                return (label, i)
303    
304            for p in self:
305                if isinstance(p, ClassGroupDefault):
306                    items.append(build_item(self.GetDefaultGroup(), _("'DEFAULT'")))
307                elif isinstance(p, ClassGroupSingleton):
308                    items.append(build_item(p, str(p.GetValue())))
309                elif isinstance(p, ClassGroupRange):
310                    items.append(build_item(p, "%s - %s" %
311                                               (p.GetMin(), p.GetMax())))
312    
313              v = data.GetStroke()          return (_("Classification"), items)
314              i.append((_("Stroke: %s") % color_string(v), v))  
315              v = data.GetStrokeWidth()  class ClassIterator:
316              i.append((_("Stroke Width: %s") % v))      """Allows the Groups in a Classifcation to be interated over.
             v = data.GetFill()  
             i.append((_("Fill: %s") % color_string(v), v))  
             return i  
317    
318          items.append((_("'DEFAULT'"), build_item(self.DefaultData)))      The items are returned in the following order:
319            default data, singletons, ranges, maps
320        """
321    
322          for name, data in self.points.items():      def __init__(self, data): #default, points, ranges, maps):
323              items.append((_("%s") % name, build_item(data)))          """Constructor.
324    
325          for p in self.ranges:          default -- the default group
326              data = p[RANGE_DATA]  
327              items.append((_("%s-%s") % (p[RANGE_MIN], p[RANGE_MAX])),          points -- a list of singleton groups
                          build_item(data))  
328    
329          return (_("Classifications"), items)          ranges -- a list of range groups
330    
331            maps -- a list of map groups
332            """
333    
334            self.data = data #[default, points, ranges, maps]
335            self.data_index = 0
336            #self.data_iter = iter(self.data)
337            #self.iter = None
338    
339        def __iter__(self):
340            return self
341    
342        def next(self):
343            """Return the next item."""
344    
345            if self.data_index >= len(self.data):
346                raise StopIteration
347            else:
348                d = self.data[self.data_index]
349                self.data_index += 1
350                return d
351            
352    #       if self.iter is None:
353    #           try:
354    #               self.data_item = self.data_iter.next()
355    #               self.iter = iter(self.data_item)
356    #           except TypeError:
357    #               return self.data_item
358    
359    #       try:
360    #           return self.iter.next()
361    #       except StopIteration:
362    #           self.iter = None
363    #           return self.next()
364          
365    class ClassGroupProperties:
366        """Represents the properties of a single Classification Group.
367      
368        These are used when rendering a layer."""
369    
370  class ClassData:      def __init__(self, props = None):
371            """Constructor.
372    
373            props -- a ClassGroupProperties object. The class is copied if
374                     prop is not None. Otherwise, a default set of properties
375                     is created such that: line color = Color.Black, line width = 1,
376                     and fill color = Color.None
377            """
378    
     def __init__(self):  
379          self.stroke = None          self.stroke = None
380          self.stroke_width = 0          self.strokeWidth = 0
381          self.fill = None          self.fill = None
382          self.label = ""  
383                if props is not None:
384      def GetStroke(self):              self.SetProperties(props)
385            else:
386                self.SetLineColor(Color.Black)
387                self.SetLineWidth(1)
388                self.SetFill(Color.None)
389    
390        def SetProperties(self, props):
391            """Set this class's properties to those in class props."""
392    
393            assert(isinstance(props, ClassGroupProperties))
394            self.SetLineColor(props.GetLineColor())
395            self.SetLineWidth(props.GetLineWidth())
396            self.SetFill(props.GetFill())
397            
398        def GetLineColor(self):
399            """Return the line color as a Color object."""
400          return self.stroke          return self.stroke
401    
402      def SetStroke(self, stroke):      def SetLineColor(self, color):
403          self.stroke = stroke          """Set the line color.
404    
405      def GetStrokeWidth(self):          color -- the color of the line. This must be a Color object.
406          return self.stroke_width          """
407    
408            assert(isinstance(color, Color))
409            self.stroke = color
410    
411        def GetLineWidth(self):
412            """Return the line width."""
413            return self.strokeWidth
414    
415        def SetLineWidth(self, lineWidth):
416            """Set the line width.
417    
418            lineWidth -- the new line width. This must be > 0.
419            """
420            assert(isinstance(lineWidth, IntType))
421            if (lineWidth < 1):
422                raise ValueError(_("lineWidth < 1"))
423    
424      def SetStrokeWidth(self, stroke_width):          self.strokeWidth = lineWidth
         self.stroke_width = stroke_width  
425    
426      def GetFill(self):      def GetFill(self):
427            """Return the fill color as a Color object."""
428          return self.fill          return self.fill
429    
430      def SetFill(self, fill):      def SetFill(self, fill):
431            """Set the fill color.
432    
433            fill -- the color of the fill. This must be a Color object.
434            """
435    
436            assert(isinstance(fill, Color))
437          self.fill = fill          self.fill = fill
438    
439        def __eq__(self, other):
440            """Return true if 'props' has the same attributes as this class"""
441    
442            return isinstance(other, ClassGroupProperties)   \
443                and self.stroke      == other.GetLineColor() \
444                and self.strokeWidth == other.GetLineWidth() \
445                and self.fill        == other.GetFill()
446    
447        def __ne__(self, other):
448            return not self.__eq__(other)
449    
450        def __copy__(self):
451            return ClassGroupProperties(self)
452    
453    class ClassGroup:
454        """A base class for all Groups within a Classification"""
455    
456        def __init__(self, label = ""):
457            """Constructor.
458    
459            label -- A string representing the Group's label
460            """
461    
462            self.label = None
463    
464            self.SetLabel(label)
465    
466      def GetLabel(self):      def GetLabel(self):
467            """Return the Group's label."""
468          return self.label          return self.label
469    
470      def SetLabel(self, label):      def SetLabel(self, label):
471            """Set the Group's label.
472    
473            label -- a string representing the Group's label. This must
474                     not be None.
475            """
476            assert(isinstance(label, StringType))
477          self.label = label          self.label = label
478    
479        def GetDisplayText(self):
480            assert(False, "GetDisplay must be overridden by subclass!")
481            return ""
482    
483        def Matches(self, value):
484            """Determines if this Group is associated with the given value.
485    
486            Returns False. This needs to be overridden by all subclasses.
487            """
488            assert(False, "GetMatches must be overridden by subclass!")
489            return False
490    
491        def GetProperties(self):
492            """Return the properties associated with the given value.
493    
494            Returns None. This needs to be overridden by all subclasses.
495            """
496            assert(False, "GetProperties must be overridden by subclass!")
497            return None
498    
499        
500    class ClassGroupSingleton(ClassGroup):
501        """A Group that is associated with a single value."""
502    
503        def __init__(self, value = 0, prop = None, label = ""):
504            """Constructor.
505    
506            value -- the associated value.
507    
508            prop -- a ClassGroupProperites object. If prop is None a default
509                     set of properties is created.
510    
511            label -- a label for this group.
512            """
513            ClassGroup.__init__(self, label)
514    
515            self.prop = None
516            self.value = None
517    
518            self.SetValue(value)
519            self.SetProperties(prop)
520    
521        def __copy__(self):
522            return ClassGroupSingleton(self.GetValue(),
523                                       self.GetProperties(),
524                                       self.GetLabel())
525    
526        def __deepcopy__(self, memo):
527            return ClassGroupSingleton(copy.copy(self.GetValue()),
528                                       copy.copy(self.GetProperties()),
529                                       copy.copy(self.GetLabel()))
530    
531        def GetValue(self):
532            """Return the associated value."""
533            return self.value
534    
535        def SetValue(self, value):
536            """Associate this Group with the given value."""
537            self.value = value
538    
539        def Matches(self, value):
540            """Determine if the given value matches the associated Group value."""
541    
542            """Returns True if the value matches, False otherwise."""
543    
544            return self.value == value
545    
546        def GetProperties(self):
547            """Return the Properties associated with this Group."""
548    
549            return self.prop
550    
551        def SetProperties(self, prop):
552            """Set the properties associated with this Group.
553    
554            prop -- a ClassGroupProperties object. if prop is None,
555                    a default set of properties is created.
556            """
557    
558            if prop is None: prop = ClassGroupProperties()
559            assert(isinstance(prop, ClassGroupProperties))
560            self.prop = prop
561    
562        def GetDisplayText(self):
563            label = self.GetLabel()
564    
565            if label != "": return label
566    
567            return str(self.GetValue())
568    
569        def __eq__(self, other):
570            return isinstance(other, ClassGroupSingleton) \
571                and self.GetProperties() == other.GetProperties() \
572                and self.GetValue() == other.GetValue()
573    
574        def __ne__(self, other):
575            return not self.__eq__(other)
576    
577    class ClassGroupDefault(ClassGroup):
578        """The default Group. When values do not match any other
579           Group within a Classification, the properties from this
580           class are used."""
581    
582        def __init__(self, prop = None, label = ""):
583            """Constructor.
584    
585            prop -- a ClassGroupProperites object. If prop is None a default
586                     set of properties is created.
587    
588            label -- a label for this group.
589            """
590    
591            ClassGroup.__init__(self, label)
592            self.SetProperties(prop)
593    
594        def __copy__(self):
595            return ClassGroupDefault(self.GetProperties(), self.GetLabel())
596    
597        def __deepcopy__(self, memo):
598            return ClassGroupDefault(copy.copy(self.GetProperties()),
599                                     copy.copy(self.GetLabel()))
600    
601        def Matches(self, value):
602            return True
603    
604        def GetProperties(self):
605            """Return the Properties associated with this Group."""
606            return self.prop
607    
608        def SetProperties(self, prop):
609            """Set the properties associated with this Group.
610    
611            prop -- a ClassGroupProperties object. if prop is None,
612                    a default set of properties is created.
613            """
614    
615            if prop is None: prop = ClassGroupProperties()
616            assert(isinstance(prop, ClassGroupProperties))
617            self.prop = prop
618    
619        def GetDisplayText(self):
620            label = self.GetLabel()
621    
622            if label != "": return label
623    
624            return "DEFAULT"
625    
626        def __eq__(self, other):
627            return isinstance(other, ClassGroupDefault) \
628                and self.GetProperties() == other.GetProperties()
629    
630        def __ne__(self, other):
631            return not self.__eq__(other)
632    
633    class ClassGroupRange(ClassGroup):
634        """A Group that represents a range of values that map to the same
635           set of properties."""
636    
637        def __init__(self, min = 0, max = 1, prop = None, label = ""):
638            """Constructor.
639    
640            The minumum value must be strictly less than the maximum.
641    
642            min -- the minimum range value
643    
644            max -- the maximum range value
645    
646            prop -- a ClassGroupProperites object. If prop is None a default
647                     set of properties is created.
648    
649            label -- a label for this group.
650            """
651    
652            ClassGroup.__init__(self, label)
653    
654            self.min = self.max = 0
655            self.prop = None
656    
657            self.SetRange(min, max)
658            self.SetProperties(prop)
659    
660        def __copy__(self):
661            return ClassGroupRange(self.GetMin(),
662                                   self.GetMax(),
663                                   self.GetProperties(),
664                                   self.GetLabel())
665    
666        def __deepcopy__(self, memo):
667            return ClassGroupRange(copy.copy(self.GetMin()),
668                                   copy.copy(self.GetMax()),
669                                   copy.copy(self.GetProperties()),
670                                   copy.copy(self.GetLabel()))
671    
672        def GetMin(self):
673            """Return the range's minimum value."""
674            return self.min
675    
676        def SetMin(self, min):
677            """Set the range's minimum value.
678        
679            min -- the new minimum. Note that this must be less than the current
680                   maximum value. Use SetRange() to change both min and max values.
681            """
682        
683            self.SetRange(min, self.max)
684    
685        def GetMax(self):
686            """Return the range's maximum value."""
687            return self.max
688    
689        def SetMax(self, max):
690            """Set the range's maximum value.
691        
692            max -- the new maximum. Note that this must be greater than the current
693                   minimum value. Use SetRange() to change both min and max values.
694            """
695            self.SetRange(self.min, max)
696    
697        def SetRange(self, min, max):
698            """Set a new range.
699    
700            Note that min must be strictly less than max.
701    
702            min -- the new minimum value
703            min -- the new maximum value
704            """
705    
706            if min >= max:
707                raise ValueError(_("ClassGroupRange: %i(min) >= %i(max)!") %
708                                 (min, max))
709            self.min = min
710            self.max = max
711    
712        def GetRange(self):
713            """Return the range as a tuple (min, max)"""
714            return (self.min, self.max)
715    
716        def Matches(self, value):
717            """Determine if the given value lies with the current range.
718    
719            The following check is used: min <= value < max.
720            """
721    
722            return self.min <= value < self.max
723    
724        def GetProperties(self):
725            """Return the Properties associated with this Group."""
726            return self.prop
727    
728        def SetProperties(self, prop):
729            """Set the properties associated with this Group.
730    
731            prop -- a ClassGroupProperties object. if prop is None,
732                    a default set of properties is created.
733            """
734            if prop is None: prop = ClassGroupProperties()
735            assert(isinstance(prop, ClassGroupProperties))
736            self.prop = prop
737    
738        def GetDisplayText(self):
739            label = self.GetLabel()
740    
741            if label != "": return label
742    
743            return _("%s - %s") % (self.GetMin(), self.GetMax())
744    
745        def __eq__(self, other):
746            return isinstance(other, ClassGroupRange) \
747                and self.GetProperties() == other.GetProperties() \
748                and self.GetRange() == other.GetRange()
749    
750        def __ne__(self, other):
751            return not self.__eq__(other)
752    
753    class ClassGroupMap(ClassGroup):
754        """Currently, this class is not used."""
755    
756        FUNC_ID = "id"
757    
758        def __init__(self, map_type = FUNC_ID, func = None, prop = None, label=""):
759            ClassGroup.__init__(self, label)
760    
761            self.map_type = map_type
762            self.func = func
763    
764            if self.func is None:
765                self.func = func_id
766    
767        def Map(self, value):
768            return self.func(value)
769    
770        def GetProperties(self):
771            return None
772    
773        def GetPropertiesFromValue(self, value):
774            pass
775    
776        def GetDisplayText(self):
777            return "Map: " + self.map_type
778    
779        #
780        # built-in mappings
781        #
782        def func_id(value):
783            return value
784    

Legend:
Removed from v.397  
changed lines
  Added in v.544

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26