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

Legend:
Removed from v.410  
changed lines
  Added in v.484

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26