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

Legend:
Removed from v.428  
changed lines
  Added in v.491

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26