/[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 453 by bh, Tue Mar 4 11:31:39 2003 UTC revision 528 by jonathan, Wed Mar 12 19:55:13 2003 UTC
# Line 23  on the mapping algorithm. Line 23  on the mapping algorithm.
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 *  from types import *
29    
30  from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \  from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \
# Line 33  from Thuban.Model.color import Color Line 35  from Thuban.Model.color import Color
35    
36  import Thuban.Model.layer  import Thuban.Model.layer
37    
   
38  # constants  # constants
39  RANGE_MIN  = 0  RANGE_MIN  = 0
40  RANGE_MAX  = 1  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 = None # stop message sending          self.layer = None
59            self.field = None
60            self.fieldType = None
61            self.groups = []
62    
63            self.__setLayerLock = False
64    
65          self.SetDefaultGroup(ClassGroupDefault())          self.SetDefaultGroup(ClassGroupDefault())
         self.SetField(field)  
66    
67          self.layer = layer          self.SetLayer(layer)
68          self.points = []          self.SetField(field)
         self.ranges = []  
         self.maps   = []  
69    
70      def __iter__(self):      def __iter__(self):
71          return ClassIterator(self.DefaultGroup,          return ClassIterator(self.groups)
                              self.points,  
                              self.ranges,  
                              self.maps)  
72    
73      def __SendMessage(self, message):      def __SendNotification(self):
74            """Notify the layer that this class has changed."""
75          if self.layer is not None:          if self.layer is not None:
76              self.layer.changed(message, self.layer)              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 == "":          if field == "":
89              field = None              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.__SendMessage(LAYER_LEGEND_CHANGED)  
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 GetFieldType(self):
118            """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):      def SetLayer(self, layer):
136          assert(isinstance(layer, Thuban.Model.layer.Layer))          """Set the owning Layer of this classification.
137          self.layer = layer  
138          self.__SendMessage(LAYER_LEGEND_CHANGED)             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            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):      def GetLayer(self):
171          return layer.self          """Return the parent layer."""
172            return self.layer
173    
174      def SetDefaultGroup(self, group):      def SetDefaultGroup(self, group):
175          """Set the group to be used when a value can't be classified.          """Set the group to be used when a value can't be classified.
176    
177             group -- group that the value maps to. See class description.             group -- group that the value maps to.
178          """          """
179    
180          assert(isinstance(group, ClassGroupDefault))          assert(isinstance(group, ClassGroupDefault))
181          self.DefaultGroup = group          self.AddGroup(group)
182    
183      def GetDefaultGroup(self):      def GetDefaultGroup(self):
184          return self.DefaultGroup          """Return the default group."""
185            return self.groups[0]
186    
187      #      #
188      # these SetDefault* methods are really only provided for      # these SetDefault* methods are really only provided for
# Line 112  class Classification: Line 191  class Classification:
191      #      #
192    
193      def SetDefaultFill(self, fill):      def SetDefaultFill(self, fill):
194            """Set the default fill color.
195    
196            fill -- a Color object.
197            """
198          assert(isinstance(fill, Color))          assert(isinstance(fill, Color))
199          self.DefaultGroup.GetProperties().SetFill(fill)          self.GetDefaultGroup().GetProperties().SetFill(fill)
200          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendNotification()
201                    
202      def GetDefaultFill(self):      def GetDefaultFill(self):
203          return self.DefaultGroup.GetProperties().GetFill()          """Return the default fill color."""
204            return self.GetDefaultGroup().GetProperties().GetFill()
205                    
206      def SetDefaultStroke(self, stroke):      def SetDefaultLineColor(self, color):
207          assert(isinstance(stroke, Color))          """Set the default line color.
208          self.DefaultGroup.GetProperties().SetStroke(stroke)  
209          self.__SendMessage(LAYER_LEGEND_CHANGED)          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.DefaultGroup.GetProperties().GetStroke()          """Return the default line color."""
217            return self.GetDefaultGroup().GetProperties().GetLineColor()
218                    
219      def SetDefaultStrokeWidth(self, strokeWidth):      def SetDefaultLineWidth(self, lineWidth):
220          assert(isinstance(strokeWidth, IntType))          """Set the default line width.
221          self.DefaultGroup.GetProperties().SetStrokeWidth(strokeWidth)  
222          self.__SendMessage(LAYER_LEGEND_CHANGED)          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.DefaultGroup.GetProperties().GetStrokeWidth()          """Return the default line width."""
230            return self.GetDefaultGroup().GetProperties().GetLineWidth()
231                    
232      def AddGroup(self, item):      def AddGroup(self, item):
233            """Add a new ClassGroup item to the classification.
234    
235            item -- this must be a valid ClassGroup object
236            """
237    
238          assert(isinstance(item, ClassGroup))          assert(isinstance(item, ClassGroup))
239    
240          if isinstance(item, ClassGroupDefault):          if len(self.groups) > 0 and isinstance(item, ClassGroupDefault):
241              self.SetDefaultGroup(item)              self.groups[0] = item
         elif isinstance(item, ClassGroupSingleton):  
             self.points.append(item)  
         elif isinstance(item, ClassGroupRange):  
             self.ranges.append(item)  
         elif isinstance(item, ClassGroupMap):  
             self.maps.append(item)  
242          else:          else:
243              raise ValueError(_("Unrecognized ClassGroup"))              self.groups.append(item)
244    
245          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendNotification()
246    
247      def GetGroup(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 properties                      the field is None or value is None,
255                        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:
259    
260              for p in self:              for i in range(1, len(self.groups)):
261                  if p.Matches(value):                  group = self.groups[i]
262                      return p                  if group.Matches(value):
263  #           #                      return group
 #           # 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  
264    
265          return self.DefaultGroup          return self.GetDefaultGroup()
266    
267      def GetProperties(self, value):      def GetProperties(self, value):
268          return self.GetGroup(value).GetProperties()          """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 = []
# Line 218  class Classification: Line 293  class Classification:
293    
294              props = group.GetProperties()              props = group.GetProperties()
295              i = []              i = []
296              v = props.GetStroke()              v = props.GetLineColor()
297              i.append(build_color_item(_("Stroke"), v))              i.append(build_color_item(_("Line Color"), v))
298              v = props.GetStrokeWidth()              v = props.GetLineWidth()
299              i.append(_("Stroke Width: %s") % v)              i.append(_("Line Width: %s") % v)
300              v = props.GetFill()              v = props.GetFill()
301              i.append(build_color_item(_("Fill"), v))              i.append(build_color_item(_("Fill"), v))
302              return (label, i)              return (label, i)
303    
304          for p in self:          for p in self:
305              if isinstance(p, ClassGroupDefault):              if isinstance(p, ClassGroupDefault):
306                  items.append(build_item(self.DefaultGroup, _("'DEFAULT'")))                  items.append(build_item(self.GetDefaultGroup(), _("'DEFAULT'")))
307              elif isinstance(p, ClassGroupSingleton):              elif isinstance(p, ClassGroupSingleton):
308                  items.append(build_item(p, str(p.GetValue())))                  items.append(build_item(p, str(p.GetValue())))
309              elif isinstance(p, ClassGroupRange):              elif isinstance(p, ClassGroupRange):
310                  items.append(build_item(p, "%s - %s" %                  items.append(build_item(p, "%s - %s" %
311                                             (p.GetMin(), p.GetMax())))                                             (p.GetMin(), p.GetMax())))
312    
 #       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())))  
   
313          return (_("Classification"), items)          return (_("Classification"), items)
314    
315  class ClassIterator:  class ClassIterator:
316        """Allows the Groups in a Classifcation to be interated over.
317    
318        The items are returned in the following order:
319            default data, singletons, ranges, maps
320        """
321    
322        def __init__(self, data): #default, points, ranges, maps):
323            """Constructor.
324    
325            default -- the default group
326    
327            points -- a list of singleton groups
328    
329      def __init__(self, default, points, ranges, maps):          ranges -- a list of range groups
330          self.data = [default, points, ranges, maps]  
331          self.data_iter = iter(self.data)          maps -- a list of map groups
332          self.iter = None          """
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):      def __iter__(self):
340          return self          return self
341    
342      def next(self):      def next(self):
343          if self.iter is None:          """Return the next item."""
344              try:  
345                  self.data_item = self.data_iter.next()          if self.data_index >= len(self.data):
346                  self.iter = iter(self.data_item)              raise StopIteration
347              except TypeError:          else:
348                  return self.data_item              d = self.data[self.data_index]
349                self.data_index += 1
350          try:              return d
351              return self.iter.next()          
352          except StopIteration:  #       if self.iter is None:
353              self.iter = None  #           try:
354              return self.next()  #               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:  class ClassGroupProperties:
366        """Represents the properties of a single Classification Group.
367      
368        These are used when rendering a layer."""
369    
370        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    
379      def __init__(self, prop = None):          self.stroke = None
380            self.strokeWidth = 0
381            self.fill = None
382    
383          if prop is not None:          if props is not None:
384              self.SetStroke(prop.GetStroke())              self.SetProperties(props)
             self.SetStrokeWidth(prop.GetStrokeWidth())  
             self.SetFill(prop.GetFill())  
385          else:          else:
386              self.SetStroke(Color.None)              self.SetLineColor(Color.Black)
387              self.SetStrokeWidth(1)              self.SetLineWidth(1)
388              self.SetFill(Color.None)              self.SetFill(Color.None)
389    
390      def GetStroke(self):      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          assert(isinstance(stroke, Color))          """Set the line color.
404          self.stroke = stroke  
405            color -- the color of the line. This must be a Color object.
406      def GetStrokeWidth(self):          """
407          return self.stroke_width  
408            assert(isinstance(color, Color))
409      def SetStrokeWidth(self, stroke_width):          self.stroke = color
410          assert(isinstance(stroke_width, IntType))  
411          if (stroke_width < 1):      def GetLineWidth(self):
412              raise ValueError(_("stroke_width < 1"))          """Return the line width."""
413            return self.strokeWidth
414    
415          self.stroke_width = stroke_width      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            self.strokeWidth = lineWidth
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))          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:  class ClassGroup:
454        """A base class for all Groups within a Classification"""
455    
456      def __init__(self, label = ""):      def __init__(self, label = ""):
457          self.label = label          """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 Matches(self, value):      def Matches(self, value):
480          """This needs to be implemented by all subclasses."""          """Determines if this Group is associated with the given value.
         pass  
481    
482      def GetProperties(self, value):          Returns False. This needs to be overridden by all subclasses.
483          """This needs to be implemented by all subclasses."""          """
484          pass          return False
485    
486        def GetProperties(self):
487            """Return the properties associated with the given value.
488    
489            Returns None. This needs to be overridden by all subclasses.
490            """
491            return None
492    
493            
494  class ClassGroupSingleton(ClassGroup):  class ClassGroupSingleton(ClassGroup):
495        """A Group that is associated with a single value."""
496    
497      def __init__(self, value = 0, prop = None, label = ""):      def __init__(self, value = 0, prop = None, label = ""):
498            """Constructor.
499    
500            value -- the associated value.
501    
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          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label)
508    
509            self.prop = None
510            self.value = None
511    
512          self.SetValue(value)          self.SetValue(value)
513          self.SetProperties(prop)          self.SetProperties(prop)
514    
515      def __copy__(self):      def __copy__(self):
516          return ClassGroupSingleton(self.value, self.prop, self.label)          return ClassGroupSingleton(self.GetValue(),
517                                       self.GetProperties(),
518                                       self.GetLabel())
519    
520        def __deepcopy__(self, memo):
521            return ClassGroupSingleton(copy.copy(self.GetValue()),
522                                       copy.copy(self.GetProperties()),
523                                       copy.copy(self.GetLabel()))
524    
525      def GetValue(self):      def GetValue(self):
526            """Return the associated value."""
527          return self.value          return self.value
528    
529      def SetValue(self, value):      def SetValue(self, value):
530            """Associate this Group with the given value."""
531          self.value = value          self.value = value
532    
533      def Matches(self, value):      def Matches(self, value):
534            """Determine if the given value matches the associated Group value."""
535    
536            """Returns True if the value matches, False otherwise."""
537    
538          return self.value == value          return self.value == value
539    
540      def GetProperties(self, value = None):      def GetProperties(self):
541          if value is None: return self.prop          """Return the Properties associated with this Group."""
542    
543          if self.Matches(value):          return self.prop
             return self.prop  
         else:  
             return None  
544    
545      def SetProperties(self, prop):      def SetProperties(self, prop):
546            """Set the properties associated with this Group.
547    
548            prop -- a ClassGroupProperties object. if prop is None,
549                    a default set of properties is created.
550            """
551    
552          if prop is None: prop = ClassGroupProperties()          if prop is None: prop = ClassGroupProperties()
553          assert(isinstance(prop, ClassGroupProperties))          assert(isinstance(prop, ClassGroupProperties))
554          self.prop = prop          self.prop = prop
555    
556        def __eq__(self, other):
557            return isinstance(other, ClassGroupSingleton) \
558                and self.GetProperties() == other.GetProperties() \
559                and self.GetValue() == other.GetValue()
560    
561        def __ne__(self, other):
562            return not self.__eq__(other)
563    
564    class ClassGroupDefault(ClassGroup):
565        """The default Group. When values do not match any other
566           Group within a Classification, the properties from this
567           class are used."""
568    
 class ClassGroupDefault(ClassGroupSingleton):  
569      def __init__(self, prop = None, label = ""):      def __init__(self, prop = None, label = ""):
570          ClassGroupSingleton.__init__(self, 0, prop, label)          """Constructor.
571    
572            prop -- a ClassGroupProperites object. If prop is None a default
573                     set of properties is created.
574    
575            label -- a label for this group.
576            """
577    
578            ClassGroup.__init__(self, label)
579            self.SetProperties(prop)
580    
581      def __copy__(self):      def __copy__(self):
582          return ClassGroupDefault(self.prop, self.label)          return ClassGroupDefault(self.GetProperties(), self.GetLabel())
583    
584      def GetProperties(self, value = None):      def __deepcopy__(self, memo):
585            return ClassGroupDefault(copy.copy(self.GetProperties()),
586                                     copy.copy(self.GetLabel()))
587    
588        def Matches(self, value):
589            return True
590    
591        def GetProperties(self):
592            """Return the Properties associated with this Group."""
593          return self.prop          return self.prop
594    
595        def SetProperties(self, prop):
596            """Set the properties associated with this Group.
597    
598            prop -- a ClassGroupProperties object. if prop is None,
599                    a default set of properties is created.
600            """
601    
602            if prop is None: prop = ClassGroupProperties()
603            assert(isinstance(prop, ClassGroupProperties))
604            self.prop = prop
605    
606        def __eq__(self, other):
607            return isinstance(other, ClassGroupDefault) \
608                and self.GetProperties() == other.GetProperties()
609    
610        def __ne__(self, other):
611            return not self.__eq__(other)
612    
613  class ClassGroupRange(ClassGroup):  class ClassGroupRange(ClassGroup):
614        """A Group that represents a range of values that map to the same
615           set of properties."""
616    
617      def __init__(self, min = 0, max = 1, prop = None, label = ""):      def __init__(self, min = 0, max = 1, prop = None, label = ""):
618            """Constructor.
619    
620            The minumum value must be strictly less than the maximum.
621    
622            min -- the minimum range value
623    
624            max -- the maximum range value
625    
626            prop -- a ClassGroupProperites object. If prop is None a default
627                     set of properties is created.
628    
629            label -- a label for this group.
630            """
631    
632          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label)
633    
634            self.min = self.max = 0
635            self.prop = None
636    
637          self.SetRange(min, max)          self.SetRange(min, max)
638          self.SetProperties(prop)          self.SetProperties(prop)
639    
640      def __copy__(self):      def __copy__(self):
641          return ClassGroupRange(self.min, self.max, self.prop, self.label)          return ClassGroupRange(self.GetMin(),
642                                   self.GetMax(),
643                                   self.GetProperties(),
644                                   self.GetLabel())
645    
646        def __deepcopy__(self, memo):
647            return ClassGroupRange(copy.copy(self.GetMin()),
648                                   copy.copy(self.GetMax()),
649                                   copy.copy(self.GetProperties()),
650                                   copy.copy(self.GetLabel()))
651    
652      def GetMin(self):      def GetMin(self):
653            """Return the range's minimum value."""
654          return self.min          return self.min
655    
656      def SetMin(self, min):      def SetMin(self, min):
657            """Set the range's minimum value.
658        
659            min -- the new minimum. Note that this must be less than the current
660                   maximum value. Use SetRange() to change both min and max values.
661            """
662        
663          self.SetRange(min, self.max)          self.SetRange(min, self.max)
664    
665      def GetMax(self):      def GetMax(self):
666            """Return the range's maximum value."""
667          return self.max          return self.max
668    
669      def SetMax(self, max):      def SetMax(self, max):
670            """Set the range's maximum value.
671        
672            max -- the new maximum. Note that this must be greater than the current
673                   minimum value. Use SetRange() to change both min and max values.
674            """
675          self.SetRange(self.min, max)          self.SetRange(self.min, max)
676    
677      def SetRange(self, min, max):      def SetRange(self, min, max):
678            """Set a new range.
679    
680            Note that min must be strictly less than max.
681    
682            min -- the new minimum value
683            min -- the new maximum value
684            """
685    
686          if min >= max:          if min >= max:
687              raise ValueError(_("ClassGroupRange: %i(min) >= %i(max)!") %              raise ValueError(_("ClassGroupRange: %i(min) >= %i(max)!") %
688                               (min, max))                               (min, max))
# Line 400  class ClassGroupRange(ClassGroup): Line 690  class ClassGroupRange(ClassGroup):
690          self.max = max          self.max = max
691    
692      def GetRange(self):      def GetRange(self):
693            """Return the range as a tuple (min, max)"""
694          return (self.min, self.max)          return (self.min, self.max)
695    
696      def Matches(self, value):      def Matches(self, value):
697          return self.min <= value < self.max          """Determine if the given value lies with the current range.
698    
699      def GetProperties(self, value = None):          The following check is used: min <= value < max.
700          if value is None: return self.prop          """
701    
702          if self.Matches(value):          return self.min <= value < self.max
703              return self.prop  
704          else:      def GetProperties(self):
705              return None          """Return the Properties associated with this Group."""
706            return self.prop
707    
708      def SetProperties(self, prop):      def SetProperties(self, prop):
709            """Set the properties associated with this Group.
710    
711            prop -- a ClassGroupProperties object. if prop is None,
712                    a default set of properties is created.
713            """
714          if prop is None: prop = ClassGroupProperties()          if prop is None: prop = ClassGroupProperties()
715          assert(isinstance(prop, ClassGroupProperties))          assert(isinstance(prop, ClassGroupProperties))
716          self.prop = prop          self.prop = prop
717    
718        def __eq__(self, other):
719            return isinstance(other, ClassGroupRange) \
720                and self.GetProperties() == other.GetProperties() \
721                and self.GetRange() == other.GetRange()
722    
723        def __ne__(self, other):
724            return not self.__eq__(other)
725    
726  class ClassGroupMap(ClassGroup):  class ClassGroupMap(ClassGroup):
727        """Currently, this class is not used."""
728    
729      FUNC_ID = "id"      FUNC_ID = "id"
730    
731      def __init__(self, map_type = FUNC_ID, func = None, prop = None, label=""):      def __init__(self, map_type = FUNC_ID, func = None, prop = None, label=""):
732          ClassGroup.__init__(self, prop)          ClassGroup.__init__(self, label)
733    
734          self.map_type = map_type          self.map_type = map_type
735          self.func = func          self.func = func
# Line 434  class ClassGroupMap(ClassGroup): Line 740  class ClassGroupMap(ClassGroup):
740      def Map(self, value):      def Map(self, value):
741          return self.func(value)          return self.func(value)
742    
743        def GetProperties(self):
744            return None
745    
746        def GetPropertiesFromValue(self, value):
747            pass
748    
749      #      #
750      # built-in mappings      # built-in mappings
751      #      #

Legend:
Removed from v.453  
changed lines
  Added in v.528

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26