/[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 528 by jonathan, Wed Mar 12 19:55:13 2003 UTC revision 1426 by jonathan, Wed Jul 16 13:22:20 2003 UTC
# 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 GetGroup() 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  import copy, operator, types
 from __future__ import nested_scopes  
24    
25  import copy  from Thuban import _
   
 from types import *  
26    
27  from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \  from messages import \
28       LAYER_VISIBILITY_CHANGED      LAYER_PROJECTION_CHANGED, \
29        LAYER_LEGEND_CHANGED, \
30        LAYER_VISIBILITY_CHANGED,\
31        CLASS_CHANGED
32    
33  from Thuban import _  from Thuban.Model.color import Color, Transparent, Black
34  from Thuban.Model.color import Color  from Thuban.Model.range import Range
35    
36  import Thuban.Model.layer  import Thuban.Model.layer
37    
38  # constants  from Thuban.Lib.connector import Publisher
 RANGE_MIN  = 0  
 RANGE_MAX  = 1  
 RANGE_DATA = 2  
   
 class Classification:  
     """Encapsulates the classification of layer. The Classification  
     divides some kind of data into Groups which are associated with  
     properties. Later the properties can be retrieved by matching  
     data values to the appropriate group."""  
39    
40      def __init__(self, layer = None, field = None):  class Classification(Publisher):
41          """Initialize a classification.      """Encapsulates the classification of layer.
42        
43             layer -- the Layer object who owns this classification      The Classification divides some kind of data into Groups which
44        are associated with properties. Later the properties can be
45        retrieved by matching data values to the appropriate group.
46        """
47    
48             field -- the name of the data table field that      def __init__(self):
49                      is to be used to classify layer properties          """Initialize a classification."""
         """  
50    
51          self.layer = None          self.__groups = []
         self.field = None  
         self.fieldType = None  
         self.groups = []  
   
         self.__setLayerLock = False  
52    
53          self.SetDefaultGroup(ClassGroupDefault())          self.SetDefaultGroup(ClassGroupDefault())
54    
         self.SetLayer(layer)  
         self.SetField(field)  
   
55      def __iter__(self):      def __iter__(self):
56          return ClassIterator(self.groups)          return ClassIterator(self.__groups)
   
     def __SendNotification(self):  
         """Notify the layer that this class has changed."""  
         if self.layer is not None:  
             self.layer.ClassChanged()  
       
     def SetField(self, field):  
         """Set the name of the data table field to use.  
           
            If there is no layer then the field type is set to None,  
            otherwise the layer is queried to find the type of the  
            field data  
   
            field -- if None then all values map to the default data  
         """  
   
         if field == "":  
             field = None  
   
   
         if field is None:  
             if self.layer is not None:  
                 self.fieldType = None  
         else:  
             if self.layer is not None:  
                 fieldType = self.layer.GetFieldType(field)  
                 if fieldType is None:  
                     raise ValueError("'%s' was not found in the layer's table."  
                                      % self.field)  
   
                 #  
                 # unfortunately we cannot call SetFieldType() because it  
                 # requires the layer to be None  
                 #  
                 self.fieldType = fieldType  
                 #self.SetFieldType(fieldType)  
   
         self.field = field  
   
         self.__SendNotification()  
   
     def GetField(self):  
         """Return the name of the field."""  
         return self.field  
   
     def GetFieldType(self):  
         """Return the field type."""  
         return self.fieldType  
   
     def SetFieldType(self, type):  
         """Set the type of the field used by this classification.  
   
         A ValueError is raised if the owning layer is not None and  
         'type' is different from the current field type.  
         """  
   
         if type != self.fieldType:  
             if self.layer is not None:  
                 raise ValueError()  
             else:  
                 self.fieldType = type  
                 self.__SendNotification()  
   
     def SetLayer(self, layer):  
         """Set the owning Layer of this classification.  
   
            A ValueError exception will be thrown either the field or  
            field type mismatch the information in the layer's table.  
         """  
   
         # prevent infinite recursion when calling SetClassification()  
         if self.__setLayerLock: return  
   
         self.__setLayerLock = True  
   
         if layer is None:  
             if self.layer is not None:  
                 l = self.layer  
                 self.layer = None  
                 l.SetClassification(None)  
         else:  
             assert(isinstance(layer, Thuban.Model.layer.Layer))  
   
             old_layer = self.layer  
   
             self.layer = layer  
57    
58              try:      def __deepcopy__(self, memo):
59                  self.SetField(self.GetField()) # this sync's the fieldType          clazz = Classification()
             except ValueError:  
                 self.layer = old_layer  
                 self.__setLayerLock = False  
                 raise ValueError  
             else:  
                 self.layer.SetClassification(self)  
   
         self.__setLayerLock = False  
   
     def GetLayer(self):  
         """Return the parent layer."""  
         return self.layer  
   
     def SetDefaultGroup(self, group):  
         """Set the group to be used when a value can't be classified.  
60    
61             group -- group that the value maps to.          clazz.__groups[0] = copy.deepcopy(self.__groups[0])
         """  
62    
63          assert(isinstance(group, ClassGroupDefault))          for i in range(1, len(self.__groups)):
64          self.AddGroup(group)              clazz.__groups.append(copy.deepcopy(self.__groups[i]))
65    
66      def GetDefaultGroup(self):          return clazz
         """Return the default group."""  
         return self.groups[0]  
67    
68        def __SendNotification(self):
69            """Notify the layer that this class has changed."""
70            self.issue(CLASS_CHANGED)
71        
72      #      #
73      # these SetDefault* methods are really only provided for      # these SetDefault* methods are really only provided for
74      # some backward compatibility. they should be considered      # some backward compatibility. they should be considered
# Line 195  class Classification: Line 80  class Classification:
80    
81          fill -- a Color object.          fill -- a Color object.
82          """          """
         assert(isinstance(fill, Color))  
83          self.GetDefaultGroup().GetProperties().SetFill(fill)          self.GetDefaultGroup().GetProperties().SetFill(fill)
84          self.__SendNotification()          self.__SendNotification()
85                    
# Line 208  class Classification: Line 92  class Classification:
92    
93          color -- a Color object.          color -- a Color object.
94          """          """
         assert(isinstance(color, Color))  
95          self.GetDefaultGroup().GetProperties().SetLineColor(color)          self.GetDefaultGroup().GetProperties().SetLineColor(color)
96          self.__SendNotification()          self.__SendNotification()
97                    
# Line 221  class Classification: Line 104  class Classification:
104    
105          lineWidth -- an integer > 0.          lineWidth -- an integer > 0.
106          """          """
107          assert(isinstance(lineWidth, IntType))          assert isinstance(lineWidth, types.IntType)
108          self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)          self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)
109          self.__SendNotification()          self.__SendNotification()
110                    
# Line 229  class Classification: Line 112  class Classification:
112          """Return the default line width."""          """Return the default line width."""
113          return self.GetDefaultGroup().GetProperties().GetLineWidth()          return self.GetDefaultGroup().GetProperties().GetLineWidth()
114                    
115      def AddGroup(self, item):  
116          """Add a new ClassGroup item to the classification.      #
117        # The methods that manipulate self.__groups have to be kept in
118        # sync. We store the default group in index 0 to make it
119        # convienent to iterate over the classification's groups, but
120        # from the user's perspective the first (non-default) group is
121        # at index 0 and the DefaultGroup is a special entity.
122        #
123    
124        def SetDefaultGroup(self, group):
125            """Set the group to be used when a value can't be classified.
126    
127            group -- group that the value maps to.
128            """
129    
130            assert isinstance(group, ClassGroupDefault)
131            if len(self.__groups) > 0:
132                self.__groups[0] = group
133            else:
134                self.__groups.append(group)
135    
136        def GetDefaultGroup(self):
137            """Return the default group."""
138            return self.__groups[0]
139    
140        def AppendGroup(self, item):
141            """Append a new ClassGroup item to the classification.
142    
143          item -- this must be a valid ClassGroup object          item -- this must be a valid ClassGroup object
144          """          """
145    
146          assert(isinstance(item, ClassGroup))          self.InsertGroup(self.GetNumGroups(), item)
147    
148          if len(self.groups) > 0 and isinstance(item, ClassGroupDefault):      def InsertGroup(self, index, group):
149              self.groups[0] = item          assert isinstance(group, ClassGroup)
150          else:          self.__groups.insert(index + 1, group)
151              self.groups.append(item)          self.__SendNotification()
152    
153        def RemoveGroup(self, index):
154            return self.__groups.pop(index + 1)
155    
156        def ReplaceGroup(self, index, group):
157            assert isinstance(group, ClassGroup)
158            self.__groups[index + 1] = group
159          self.__SendNotification()          self.__SendNotification()
160    
161      def GetGroup(self, value):      def GetGroup(self, index):
162            return self.__groups[index + 1]
163    
164        def GetNumGroups(self):
165            """Return the number of non-default groups in the classification."""
166            return len(self.__groups) - 1
167    
168        def FindGroup(self, value):
169          """Return the associated group, or the default group.          """Return the associated group, or the default group.
170    
171             Groups are checked in the order the were added to the          Groups are checked in the order the were added to the
172             Classification.          Classification.
173    
174             value -- the value to classify. If there is no mapping,          value -- the value to classify. If there is no mapping,
175                      the field is None or value is None,                   the field is None or value is None,
176                      return the default properties                   return the default properties
177          """          """
178    
179          if self.GetField() is not None and value is not None:          if value is not None:
180                for i in range(1, len(self.__groups)):
181              for i in range(1, len(self.groups)):                  group = self.__groups[i]
                 group = self.groups[i]  
182                  if group.Matches(value):                  if group.Matches(value):
183                      return group                      return group
184    
185          return self.GetDefaultGroup()          return self.GetDefaultGroup()
186    
187      def GetProperties(self, value):      def GetProperties(self, value):
188          """Return the properties associated with the given value."""          """Return the properties associated with the given value.
189          
190            Use this function rather than Classification.FindGroup().GetProperties()
191            since the returned group may be a ClassGroupMap which doesn't support
192            a call to GetProperties().
193            """
194    
195          group = self.GetGroup(value)          group = self.FindGroup(value)
196          if isinstance(group, ClassGroupMap):          if isinstance(group, ClassGroupMap):
197              return group.GetPropertiesFromValue(value)              return group.GetPropertiesFromValue(value)
198          else:          else:
# Line 277  class Classification: Line 202  class Classification:
202          items = []          items = []
203    
204          def build_color_item(text, color):          def build_color_item(text, color):
205              if color is Color.None:              if color is Transparent:
206                  return ("%s: %s" % (text, _("None")), None)                  return ("%s: %s" % (text, _("None")), None)
207    
208              return ("%s: (%.3f, %.3f, %.3f)" %              return ("%s: (%.3f, %.3f, %.3f)" %
# Line 302  class Classification: Line 227  class Classification:
227              return (label, i)              return (label, i)
228    
229          for p in self:          for p in self:
230              if isinstance(p, ClassGroupDefault):              items.append(build_item(p, p.GetDisplayText()))
                 items.append(build_item(self.GetDefaultGroup(), _("'DEFAULT'")))  
             elif isinstance(p, ClassGroupSingleton):  
                 items.append(build_item(p, str(p.GetValue())))  
             elif isinstance(p, ClassGroupRange):  
                 items.append(build_item(p, "%s - %s" %  
                                            (p.GetMin(), p.GetMax())))  
231    
232          return (_("Classification"), items)          return (_("Classification"), items)
233    
# Line 331  class ClassIterator: Line 250  class ClassIterator:
250          maps -- a list of map groups          maps -- a list of map groups
251          """          """
252    
253          self.data = data #[default, points, ranges, maps]          self.data = data
254          self.data_index = 0          self.data_index = 0
         #self.data_iter = iter(self.data)  
         #self.iter = None  
255    
256      def __iter__(self):      def __iter__(self):
257          return self          return self
# Line 349  class ClassIterator: Line 266  class ClassIterator:
266              self.data_index += 1              self.data_index += 1
267              return d              return d
268                    
 #       if self.iter is None:  
 #           try:  
 #               self.data_item = self.data_iter.next()  
 #               self.iter = iter(self.data_item)  
 #           except TypeError:  
 #               return self.data_item  
   
 #       try:  
 #           return self.iter.next()  
 #       except StopIteration:  
 #           self.iter = None  
 #           return self.next()  
         
269  class ClassGroupProperties:  class ClassGroupProperties:
270      """Represents the properties of a single Classification Group.      """Represents the properties of a single Classification Group.
271        
# Line 372  class ClassGroupProperties: Line 276  class ClassGroupProperties:
276    
277          props -- a ClassGroupProperties object. The class is copied if          props -- a ClassGroupProperties object. The class is copied if
278                   prop is not None. Otherwise, a default set of properties                   prop is not None. Otherwise, a default set of properties
279                   is created such that: line color = Color.Black, line width = 1,                   is created such that: line color = Black, line width = 1,
280                   and fill color = Color.None                   and fill color = Transparent
281          """          """
282    
         self.stroke = None  
         self.strokeWidth = 0  
         self.fill = None  
   
283          if props is not None:          if props is not None:
284              self.SetProperties(props)              self.SetProperties(props)
285          else:          else:
286              self.SetLineColor(Color.Black)              self.SetLineColor(Black)
287              self.SetLineWidth(1)              self.SetLineWidth(1)
288              self.SetFill(Color.None)              self.SetFill(Transparent)
289    
290      def SetProperties(self, props):      def SetProperties(self, props):
291          """Set this class's properties to those in class props."""          """Set this class's properties to those in class props."""
292    
293          assert(isinstance(props, ClassGroupProperties))          assert isinstance(props, ClassGroupProperties)
294          self.SetLineColor(props.GetLineColor())          self.SetLineColor(props.GetLineColor())
295          self.SetLineWidth(props.GetLineWidth())          self.SetLineWidth(props.GetLineWidth())
296          self.SetFill(props.GetFill())          self.SetFill(props.GetFill())
297                    
298      def GetLineColor(self):      def GetLineColor(self):
299          """Return the line color as a Color object."""          """Return the line color as a Color object."""
300          return self.stroke          return self.__stroke
301    
302      def SetLineColor(self, color):      def SetLineColor(self, color):
303          """Set the line color.          """Set the line color.
# Line 405  class ClassGroupProperties: Line 305  class ClassGroupProperties:
305          color -- the color of the line. This must be a Color object.          color -- the color of the line. This must be a Color object.
306          """          """
307    
308          assert(isinstance(color, Color))          self.__stroke = color
         self.stroke = color  
309    
310      def GetLineWidth(self):      def GetLineWidth(self):
311          """Return the line width."""          """Return the line width."""
312          return self.strokeWidth          return self.__strokeWidth
313    
314      def SetLineWidth(self, lineWidth):      def SetLineWidth(self, lineWidth):
315          """Set the line width.          """Set the line width.
316    
317          lineWidth -- the new line width. This must be > 0.          lineWidth -- the new line width. This must be > 0.
318          """          """
319          assert(isinstance(lineWidth, IntType))          assert isinstance(lineWidth, types.IntType)
320          if (lineWidth < 1):          if (lineWidth < 1):
321              raise ValueError(_("lineWidth < 1"))              raise ValueError(_("lineWidth < 1"))
322    
323          self.strokeWidth = lineWidth          self.__strokeWidth = lineWidth
324    
325      def GetFill(self):      def GetFill(self):
326          """Return the fill color as a Color object."""          """Return the fill color as a Color object."""
327          return self.fill          return self.__fill
328    
329      def SetFill(self, fill):      def SetFill(self, fill):
330          """Set the fill color.          """Set the fill color.
# Line 433  class ClassGroupProperties: Line 332  class ClassGroupProperties:
332          fill -- the color of the fill. This must be a Color object.          fill -- the color of the fill. This must be a Color object.
333          """          """
334    
335          assert(isinstance(fill, Color))          self.__fill = fill
         self.fill = fill  
336    
337      def __eq__(self, other):      def __eq__(self, other):
338          """Return true if 'props' has the same attributes as this class"""          """Return true if 'props' has the same attributes as this class"""
339    
340            #
341            # using 'is' over '==' results in a huge performance gain
342            # in the renderer
343            #
344          return isinstance(other, ClassGroupProperties)   \          return isinstance(other, ClassGroupProperties)   \
345              and self.stroke      == other.GetLineColor() \              and (self.__stroke is other.__stroke or      \
346              and self.strokeWidth == other.GetLineWidth() \                   self.__stroke == other.__stroke)        \
347              and self.fill        == other.GetFill()              and (self.__fill is other.__fill or          \
348                     self.__fill == other.__fill)            \
349                and self.__strokeWidth == other.__strokeWidth
350    
351      def __ne__(self, other):      def __ne__(self, other):
352          return not self.__eq__(other)          return not self.__eq__(other)
# Line 450  class ClassGroupProperties: Line 354  class ClassGroupProperties:
354      def __copy__(self):      def __copy__(self):
355          return ClassGroupProperties(self)          return ClassGroupProperties(self)
356    
357        def __deepcopy__(self):
358            return ClassGroupProperties(self)
359    
360        def __repr__(self):
361            return repr((self.__stroke, self.__strokeWidth, self.__fill))
362    
363  class ClassGroup:  class ClassGroup:
364      """A base class for all Groups within a Classification"""      """A base class for all Groups within a Classification"""
365    
366      def __init__(self, label = ""):      def __init__(self, label = "", props = None, group = None):
367          """Constructor.          """Constructor.
368    
369          label -- A string representing the Group's label          label -- A string representing the Group's label
370          """          """
371    
372          self.label = None          if group is not None:
373                self.SetLabel(copy.copy(group.GetLabel()))
374          self.SetLabel(label)              self.SetProperties(copy.copy(group.GetProperties()))
375                self.SetVisible(group.IsVisible())
376            else:
377                self.SetLabel(label)
378                self.SetProperties(props)
379                self.SetVisible(True)
380    
381      def GetLabel(self):      def GetLabel(self):
382          """Return the Group's label."""          """Return the Group's label."""
# Line 473  class ClassGroup: Line 388  class ClassGroup:
388          label -- a string representing the Group's label. This must          label -- a string representing the Group's label. This must
389                   not be None.                   not be None.
390          """          """
391          assert(isinstance(label, StringType))          assert isinstance(label, types.StringTypes)
392          self.label = label          self.label = label
393    
394        def GetDisplayText(self):
395            assert False, "GetDisplay must be overridden by subclass!"
396            return ""
397    
398      def Matches(self, value):      def Matches(self, value):
399          """Determines if this Group is associated with the given value.          """Determines if this Group is associated with the given value.
400    
401          Returns False. This needs to be overridden by all subclasses.          Returns False. This needs to be overridden by all subclasses.
402          """          """
403            assert False, "GetMatches must be overridden by subclass!"
404          return False          return False
405    
406      def GetProperties(self):      def GetProperties(self):
407          """Return the properties associated with the given value.          """Return the properties associated with the given value."""
408    
409          Returns None. This needs to be overridden by all subclasses.          return self.prop
         """  
         return None  
410    
411        def SetProperties(self, prop):
412            """Set the properties associated with this Group.
413    
414            prop -- a ClassGroupProperties object. if prop is None,
415                    a default set of properties is created.
416            """
417    
418            if prop is None: prop = ClassGroupProperties()
419            assert isinstance(prop, ClassGroupProperties)
420            self.prop = prop
421    
422        def IsVisible(self):
423            return self.visible
424    
425        def SetVisible(self, visible):
426            self.visible = visible
427    
428        def __eq__(self, other):
429            return isinstance(other, ClassGroup) \
430                and self.label == other.label \
431                and self.GetProperties() == other.GetProperties()
432    
433        def __ne__(self, other):
434            return not self.__eq__(other)
435    
436        def __repr__(self):
437            return repr(self.label) + ", " + repr(self.GetProperties())
438            
439  class ClassGroupSingleton(ClassGroup):  class ClassGroupSingleton(ClassGroup):
440      """A Group that is associated with a single value."""      """A Group that is associated with a single value."""
441    
442      def __init__(self, value = 0, prop = None, label = ""):      def __init__(self, value = 0, props = None, label = "", group = None):
443          """Constructor.          """Constructor.
444    
445          value -- the associated value.          value -- the associated value.
# Line 504  class ClassGroupSingleton(ClassGroup): Line 449  class ClassGroupSingleton(ClassGroup):
449    
450          label -- a label for this group.          label -- a label for this group.
451          """          """
452          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label, props, group)
   
         self.prop = None  
         self.value = None  
453    
454          self.SetValue(value)          self.SetValue(value)
         self.SetProperties(prop)  
455    
456      def __copy__(self):      def __copy__(self):
457          return ClassGroupSingleton(self.GetValue(),          return ClassGroupSingleton(self.GetValue(),
# Line 518  class ClassGroupSingleton(ClassGroup): Line 459  class ClassGroupSingleton(ClassGroup):
459                                     self.GetLabel())                                     self.GetLabel())
460    
461      def __deepcopy__(self, memo):      def __deepcopy__(self, memo):
462          return ClassGroupSingleton(copy.copy(self.GetValue()),          return ClassGroupSingleton(self.GetValue(), group = self)
                                    copy.copy(self.GetProperties()),  
                                    copy.copy(self.GetLabel()))  
463    
464      def GetValue(self):      def GetValue(self):
465          """Return the associated value."""          """Return the associated value."""
466          return self.value          return self.__value
467    
468      def SetValue(self, value):      def SetValue(self, value):
469          """Associate this Group with the given value."""          """Associate this Group with the given value."""
470          self.value = value          self.__value = value
471    
472      def Matches(self, value):      def Matches(self, value):
473          """Determine if the given value matches the associated Group value."""          """Determine if the given value matches the associated Group value."""
474    
475          """Returns True if the value matches, False otherwise."""          """Returns True if the value matches, False otherwise."""
476    
477          return self.value == value          return self.__value == value
478    
479      def GetProperties(self):      def GetDisplayText(self):
480          """Return the Properties associated with this Group."""          label = self.GetLabel()
481    
482          return self.prop          if label != "": return label
483    
484      def SetProperties(self, prop):          return str(self.GetValue())
         """Set the properties associated with this Group.  
   
         prop -- a ClassGroupProperties object. if prop is None,  
                 a default set of properties is created.  
         """  
   
         if prop is None: prop = ClassGroupProperties()  
         assert(isinstance(prop, ClassGroupProperties))  
         self.prop = prop  
485    
486      def __eq__(self, other):      def __eq__(self, other):
487          return isinstance(other, ClassGroupSingleton) \          return ClassGroup.__eq__(self, other) \
488              and self.GetProperties() == other.GetProperties() \              and isinstance(other, ClassGroupSingleton) \
489              and self.GetValue() == other.GetValue()              and self.__value == other.__value
490    
491      def __ne__(self, other):      def __repr__(self):
492          return not self.__eq__(other)          return "(" + repr(self.__value) + ", " + ClassGroup.__repr__(self) + ")"
493    
494  class ClassGroupDefault(ClassGroup):  class ClassGroupDefault(ClassGroup):
495      """The default Group. When values do not match any other      """The default Group. When values do not match any other
496         Group within a Classification, the properties from this         Group within a Classification, the properties from this
497         class are used."""         class are used."""
498    
499      def __init__(self, prop = None, label = ""):      def __init__(self, props = None, label = "", group = None):
500          """Constructor.          """Constructor.
501    
502          prop -- a ClassGroupProperites object. If prop is None a default          prop -- a ClassGroupProperites object. If prop is None a default
# Line 575  class ClassGroupDefault(ClassGroup): Line 505  class ClassGroupDefault(ClassGroup):
505          label -- a label for this group.          label -- a label for this group.
506          """          """
507    
508          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label, props, group)
         self.SetProperties(prop)  
509    
510      def __copy__(self):      def __copy__(self):
511          return ClassGroupDefault(self.GetProperties(), self.GetLabel())          return ClassGroupDefault(self.GetProperties(), self.GetLabel())
512    
513      def __deepcopy__(self, memo):      def __deepcopy__(self, memo):
514          return ClassGroupDefault(copy.copy(self.GetProperties()),          return ClassGroupDefault(label = self.GetLabel(), group = self)
                                  copy.copy(self.GetLabel()))  
515    
516      def Matches(self, value):      def Matches(self, value):
517          return True          return True
518    
519      def GetProperties(self):      def GetDisplayText(self):
520          """Return the Properties associated with this Group."""          label = self.GetLabel()
         return self.prop  
521    
522      def SetProperties(self, prop):          if label != "": return label
         """Set the properties associated with this Group.  
523    
524          prop -- a ClassGroupProperties object. if prop is None,          return _("DEFAULT")
                 a default set of properties is created.  
         """  
   
         if prop is None: prop = ClassGroupProperties()  
         assert(isinstance(prop, ClassGroupProperties))  
         self.prop = prop  
525    
526      def __eq__(self, other):      def __eq__(self, other):
527          return isinstance(other, ClassGroupDefault) \          return ClassGroup.__eq__(self, other) \
528                and isinstance(other, ClassGroupDefault) \
529              and self.GetProperties() == other.GetProperties()              and self.GetProperties() == other.GetProperties()
530    
531      def __ne__(self, other):      def __repr__(self):
532          return not self.__eq__(other)          return "(" + ClassGroup.__repr__(self) + ")"
533    
534  class ClassGroupRange(ClassGroup):  class ClassGroupRange(ClassGroup):
535      """A Group that represents a range of values that map to the same      """A Group that represents a range of values that map to the same
536         set of properties."""         set of properties."""
537    
538      def __init__(self, min = 0, max = 1, prop = None, label = ""):      def __init__(self, _range = (0,1), props = None, label = "", group=None):
539          """Constructor.          """Constructor.
540    
541          The minumum value must be strictly less than the maximum.          The minumum value must be strictly less than the maximum.
542    
543          min -- the minimum range value          _range -- either a tuple (min, max) where min < max or
544                      a Range object
         max -- the maximum range value  
545    
546          prop -- a ClassGroupProperites object. If prop is None a default          prop -- a ClassGroupProperites object. If prop is None a default
547                   set of properties is created.                   set of properties is created.
# Line 629  class ClassGroupRange(ClassGroup): Line 549  class ClassGroupRange(ClassGroup):
549          label -- a label for this group.          label -- a label for this group.
550          """          """
551    
552          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label, props, group)
553            self.SetRange(_range)
         self.min = self.max = 0  
         self.prop = None  
   
         self.SetRange(min, max)  
         self.SetProperties(prop)  
554    
555      def __copy__(self):      def __copy__(self):
556          return ClassGroupRange(self.GetMin(),          return ClassGroupRange(self.__range,
557                                 self.GetMax(),                                 props = self.GetProperties(),
558                                 self.GetProperties(),                                 label = self.GetLabel())
                                self.GetLabel())  
559    
560      def __deepcopy__(self, memo):      def __deepcopy__(self, memo):
561          return ClassGroupRange(copy.copy(self.GetMin()),          return ClassGroupRange(copy.copy(self.__range),
562                                 copy.copy(self.GetMax()),                                 group = self)
                                copy.copy(self.GetProperties()),  
                                copy.copy(self.GetLabel()))  
563    
564      def GetMin(self):      def GetMin(self):
565          """Return the range's minimum value."""          """Return the range's minimum value."""
566          return self.min          return self.__range.GetRange()[1]
567    
568      def SetMin(self, min):      def SetMin(self, min):
569          """Set the range's minimum value.          """Set the range's minimum value.
# Line 660  class ClassGroupRange(ClassGroup): Line 572  class ClassGroupRange(ClassGroup):
572                 maximum value. Use SetRange() to change both min and max values.                 maximum value. Use SetRange() to change both min and max values.
573          """          """
574            
575          self.SetRange(min, self.max)          self.SetRange((min, self.__range.GetRange()[2]))
576    
577      def GetMax(self):      def GetMax(self):
578          """Return the range's maximum value."""          """Return the range's maximum value."""
579          return self.max          return self.__range.GetRange()[2]
580    
581      def SetMax(self, max):      def SetMax(self, max):
582          """Set the range's maximum value.          """Set the range's maximum value.
# Line 672  class ClassGroupRange(ClassGroup): Line 584  class ClassGroupRange(ClassGroup):
584          max -- the new maximum. Note that this must be greater than the current          max -- the new maximum. Note that this must be greater than the current
585                 minimum value. Use SetRange() to change both min and max values.                 minimum value. Use SetRange() to change both min and max values.
586          """          """
587          self.SetRange(self.min, max)          self.SetRange((self.__range.GetRange()[1], max))
588    
589      def SetRange(self, min, max):      def SetRange(self, _range):
590          """Set a new range.          """Set a new range.
591    
592          Note that min must be strictly less than max.          _range -- Either a tuple (min, max) where min < max or
593                      a Range object.
594    
595          min -- the new minimum value          Raises ValueError on error.
         min -- the new maximum value  
596          """          """
597    
598          if min >= max:          if isinstance(_range, Range):
599              raise ValueError(_("ClassGroupRange: %i(min) >= %i(max)!") %              self.__range = _range
600                               (min, max))          elif isinstance(_range, types.TupleType) and len(_range) == 2:
601          self.min = min              self.__range = Range(("[", _range[0], _range[1], "["))
602          self.max = max          else:
603                raise ValueError()
604    
605      def GetRange(self):      def GetRange(self):
606          """Return the range as a tuple (min, max)"""          """Return the range as a string"""
607          return (self.min, self.max)          return self.__range.string(self.__range.GetRange())
608    
609      def Matches(self, value):      def Matches(self, value):
610          """Determine if the given value lies with the current range.          """Determine if the given value lies with the current range.
# Line 699  class ClassGroupRange(ClassGroup): Line 612  class ClassGroupRange(ClassGroup):
612          The following check is used: min <= value < max.          The following check is used: min <= value < max.
613          """          """
614    
615          return self.min <= value < self.max          return operator.contains(self.__range, value)
616    
617      def GetProperties(self):      def GetDisplayText(self):
618          """Return the Properties associated with this Group."""          label = self.GetLabel()
         return self.prop  
619    
620      def SetProperties(self, prop):          if label != "": return label
         """Set the properties associated with this Group.  
621    
622          prop -- a ClassGroupProperties object. if prop is None,          return self.__range.string(self.__range.GetRange())
                 a default set of properties is created.  
         """  
         if prop is None: prop = ClassGroupProperties()  
         assert(isinstance(prop, ClassGroupProperties))  
         self.prop = prop  
623    
624      def __eq__(self, other):      def __eq__(self, other):
625          return isinstance(other, ClassGroupRange) \          return ClassGroup.__eq__(self, other) \
626              and self.GetProperties() == other.GetProperties() \              and isinstance(other, ClassGroupRange) \
627              and self.GetRange() == other.GetRange()              and self.__range == other.__range
628    
629      def __ne__(self, other):      def __repr__(self):
630          return not self.__eq__(other)          return "(" + str(self.__range) + ClassGroup.__repr__(self) + ")"
631    
632  class ClassGroupMap(ClassGroup):  class ClassGroupMap(ClassGroup):
633      """Currently, this class is not used."""      """Currently, this class is not used."""
# Line 746  class ClassGroupMap(ClassGroup): Line 652  class ClassGroupMap(ClassGroup):
652      def GetPropertiesFromValue(self, value):      def GetPropertiesFromValue(self, value):
653          pass          pass
654    
655        def GetDisplayText(self):
656            return "Map: " + self.map_type
657    
658      #      #
659      # built-in mappings      # built-in mappings
660      #      #

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26