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

Legend:
Removed from v.378  
changed lines
  Added in v.613

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26