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

Legend:
Removed from v.381  
changed lines
  Added in v.602

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26