/[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 1909 by bh, Fri Oct 31 18:16:34 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            assert isinstance(group, ClassGroupDefault)
130            if len(self.__groups) > 0:
131                self.__groups[0] = group
132            else:
133                self.__groups.append(group)
134            self.__SendNotification()
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            """Remove the classification group with the given index"""
155            self.__groups.pop(index + 1)
156          self.__SendNotification()          self.__SendNotification()
157    
158      def GetGroup(self, value):      def ReplaceGroup(self, index, group):
159            assert isinstance(group, ClassGroup)
160            self.__groups[index + 1] = group
161            self.__SendNotification()
162    
163        def GetGroup(self, index):
164            return self.__groups[index + 1]
165    
166        def GetNumGroups(self):
167            """Return the number of non-default groups in the classification."""
168            return len(self.__groups) - 1
169    
170        def FindGroup(self, value):
171          """Return the associated group, or the default group.          """Return the associated group, or the default group.
172    
173             Groups are checked in the order the were added to the          Groups are checked in the order the were added to the
174             Classification.          Classification.
175    
176             value -- the value to classify. If there is no mapping,          value -- the value to classify. If there is no mapping,
177                      the field is None or value is None,                   the field is None or value is None,
178                      return the default properties                   return the default properties
179          """          """
180    
181          if self.GetField() is not None and value is not None:          if value is not None:
182                for i in range(1, len(self.__groups)):
183              for i in range(1, len(self.groups)):                  group = self.__groups[i]
                 group = self.groups[i]  
184                  if group.Matches(value):                  if group.Matches(value):
185                      return group                      return group
186    
187          return self.GetDefaultGroup()          return self.GetDefaultGroup()
188    
189      def GetProperties(self, value):      def GetProperties(self, value):
190          """Return the properties associated with the given value."""          """Return the properties associated with the given value.
191          
192            Use this function rather than Classification.FindGroup().GetProperties()
193            since the returned group may be a ClassGroupMap which doesn't support
194            a call to GetProperties().
195            """
196    
197          group = self.GetGroup(value)          group = self.FindGroup(value)
198          if isinstance(group, ClassGroupMap):          if isinstance(group, ClassGroupMap):
199              return group.GetPropertiesFromValue(value)              return group.GetPropertiesFromValue(value)
200          else:          else:
# Line 277  class Classification: Line 204  class Classification:
204          items = []          items = []
205    
206          def build_color_item(text, color):          def build_color_item(text, color):
207              if color is Color.None:              if color is Transparent:
208                  return ("%s: %s" % (text, _("None")), None)                  return ("%s: %s" % (text, _("None")), None)
209    
210              return ("%s: (%.3f, %.3f, %.3f)" %              return ("%s: (%.3f, %.3f, %.3f)" %
# Line 302  class Classification: Line 229  class Classification:
229              return (label, i)              return (label, i)
230    
231          for p in self:          for p in self:
232              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())))  
233    
234          return (_("Classification"), items)          return (_("Classification"), items)
235    
# Line 331  class ClassIterator: Line 252  class ClassIterator:
252          maps -- a list of map groups          maps -- a list of map groups
253          """          """
254    
255          self.data = data #[default, points, ranges, maps]          self.data = data
256          self.data_index = 0          self.data_index = 0
         #self.data_iter = iter(self.data)  
         #self.iter = None  
257    
258      def __iter__(self):      def __iter__(self):
259          return self          return self
# Line 349  class ClassIterator: Line 268  class ClassIterator:
268              self.data_index += 1              self.data_index += 1
269              return d              return d
270                    
 #       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()  
         
271  class ClassGroupProperties:  class ClassGroupProperties:
272      """Represents the properties of a single Classification Group.      """Represents the properties of a single Classification Group.
273        
# Line 372  class ClassGroupProperties: Line 278  class ClassGroupProperties:
278    
279          props -- a ClassGroupProperties object. The class is copied if          props -- a ClassGroupProperties object. The class is copied if
280                   prop is not None. Otherwise, a default set of properties                   prop is not None. Otherwise, a default set of properties
281                   is created such that: line color = Color.Black, line width = 1,                   is created such that: line color = Black, line width = 1,
282                   and fill color = Color.None                   and fill color = Transparent
283          """          """
284    
         self.stroke = None  
         self.strokeWidth = 0  
         self.fill = None  
   
285          if props is not None:          if props is not None:
286              self.SetProperties(props)              self.SetProperties(props)
287          else:          else:
288              self.SetLineColor(Color.Black)              self.SetLineColor(Black)
289              self.SetLineWidth(1)              self.SetLineWidth(1)
290              self.SetFill(Color.None)              self.SetFill(Transparent)
291    
292      def SetProperties(self, props):      def SetProperties(self, props):
293          """Set this class's properties to those in class props."""          """Set this class's properties to those in class props."""
294    
295          assert(isinstance(props, ClassGroupProperties))          assert isinstance(props, ClassGroupProperties)
296          self.SetLineColor(props.GetLineColor())          self.SetLineColor(props.GetLineColor())
297          self.SetLineWidth(props.GetLineWidth())          self.SetLineWidth(props.GetLineWidth())
298          self.SetFill(props.GetFill())          self.SetFill(props.GetFill())
299                    
300      def GetLineColor(self):      def GetLineColor(self):
301          """Return the line color as a Color object."""          """Return the line color as a Color object."""
302          return self.stroke          return self.__stroke
303    
304      def SetLineColor(self, color):      def SetLineColor(self, color):
305          """Set the line color.          """Set the line color.
# Line 405  class ClassGroupProperties: Line 307  class ClassGroupProperties:
307          color -- the color of the line. This must be a Color object.          color -- the color of the line. This must be a Color object.
308          """          """
309    
310          assert(isinstance(color, Color))          self.__stroke = color
         self.stroke = color  
311    
312      def GetLineWidth(self):      def GetLineWidth(self):
313          """Return the line width."""          """Return the line width."""
314          return self.strokeWidth          return self.__strokeWidth
315    
316      def SetLineWidth(self, lineWidth):      def SetLineWidth(self, lineWidth):
317          """Set the line width.          """Set the line width.
318    
319          lineWidth -- the new line width. This must be > 0.          lineWidth -- the new line width. This must be > 0.
320          """          """
321          assert(isinstance(lineWidth, IntType))          assert isinstance(lineWidth, types.IntType)
322          if (lineWidth < 1):          if (lineWidth < 1):
323              raise ValueError(_("lineWidth < 1"))              raise ValueError(_("lineWidth < 1"))
324    
325          self.strokeWidth = lineWidth          self.__strokeWidth = lineWidth
326    
327      def GetFill(self):      def GetFill(self):
328          """Return the fill color as a Color object."""          """Return the fill color as a Color object."""
329          return self.fill          return self.__fill
330    
331      def SetFill(self, fill):      def SetFill(self, fill):
332          """Set the fill color.          """Set the fill color.
# Line 433  class ClassGroupProperties: Line 334  class ClassGroupProperties:
334          fill -- the color of the fill. This must be a Color object.          fill -- the color of the fill. This must be a Color object.
335          """          """
336    
337          assert(isinstance(fill, Color))          self.__fill = fill
         self.fill = fill  
338    
339      def __eq__(self, other):      def __eq__(self, other):
340          """Return true if 'props' has the same attributes as this class"""          """Return true if 'props' has the same attributes as this class"""
341    
342            #
343            # using 'is' over '==' results in a huge performance gain
344            # in the renderer
345            #
346          return isinstance(other, ClassGroupProperties)   \          return isinstance(other, ClassGroupProperties)   \
347              and self.stroke      == other.GetLineColor() \              and (self.__stroke is other.__stroke or      \
348              and self.strokeWidth == other.GetLineWidth() \                   self.__stroke == other.__stroke)        \
349              and self.fill        == other.GetFill()              and (self.__fill is other.__fill or          \
350                     self.__fill == other.__fill)            \
351                and self.__strokeWidth == other.__strokeWidth
352    
353      def __ne__(self, other):      def __ne__(self, other):
354          return not self.__eq__(other)          return not self.__eq__(other)
# Line 450  class ClassGroupProperties: Line 356  class ClassGroupProperties:
356      def __copy__(self):      def __copy__(self):
357          return ClassGroupProperties(self)          return ClassGroupProperties(self)
358    
359        def __deepcopy__(self):
360            return ClassGroupProperties(self)
361    
362        def __repr__(self):
363            return repr((self.__stroke, self.__strokeWidth, self.__fill))
364    
365  class ClassGroup:  class ClassGroup:
366      """A base class for all Groups within a Classification"""      """A base class for all Groups within a Classification"""
367    
368      def __init__(self, label = ""):      def __init__(self, label = "", props = None, group = None):
369          """Constructor.          """Constructor.
370    
371          label -- A string representing the Group's label          label -- A string representing the Group's label
372          """          """
373    
374          self.label = None          if group is not None:
375                self.SetLabel(copy.copy(group.GetLabel()))
376          self.SetLabel(label)              self.SetProperties(copy.copy(group.GetProperties()))
377                self.SetVisible(group.IsVisible())
378            else:
379                self.SetLabel(label)
380                self.SetProperties(props)
381                self.SetVisible(True)
382    
383      def GetLabel(self):      def GetLabel(self):
384          """Return the Group's label."""          """Return the Group's label."""
# Line 473  class ClassGroup: Line 390  class ClassGroup:
390          label -- a string representing the Group's label. This must          label -- a string representing the Group's label. This must
391                   not be None.                   not be None.
392          """          """
393          assert(isinstance(label, StringType))          assert isinstance(label, types.StringTypes)
394          self.label = label          self.label = label
395    
396        def GetDisplayText(self):
397            assert False, "GetDisplay must be overridden by subclass!"
398            return ""
399    
400      def Matches(self, value):      def Matches(self, value):
401          """Determines if this Group is associated with the given value.          """Determines if this Group is associated with the given value.
402    
403          Returns False. This needs to be overridden by all subclasses.          Returns False. This needs to be overridden by all subclasses.
404          """          """
405            assert False, "GetMatches must be overridden by subclass!"
406          return False          return False
407    
408      def GetProperties(self):      def GetProperties(self):
409          """Return the properties associated with the given value.          """Return the properties associated with the given value."""
410    
411          Returns None. This needs to be overridden by all subclasses.          return self.prop
         """  
         return None  
412    
413        def SetProperties(self, prop):
414            """Set the properties associated with this Group.
415    
416            prop -- a ClassGroupProperties object. if prop is None,
417                    a default set of properties is created.
418            """
419    
420            if prop is None: prop = ClassGroupProperties()
421            assert isinstance(prop, ClassGroupProperties)
422            self.prop = prop
423    
424        def IsVisible(self):
425            return self.visible
426    
427        def SetVisible(self, visible):
428            self.visible = visible
429    
430        def __eq__(self, other):
431            return isinstance(other, ClassGroup) \
432                and self.label == other.label \
433                and self.GetProperties() == other.GetProperties()
434    
435        def __ne__(self, other):
436            return not self.__eq__(other)
437    
438        def __repr__(self):
439            return repr(self.label) + ", " + repr(self.GetProperties())
440            
441  class ClassGroupSingleton(ClassGroup):  class ClassGroupSingleton(ClassGroup):
442      """A Group that is associated with a single value."""      """A Group that is associated with a single value."""
443    
444      def __init__(self, value = 0, prop = None, label = ""):      def __init__(self, value = 0, props = None, label = "", group = None):
445          """Constructor.          """Constructor.
446    
447          value -- the associated value.          value -- the associated value.
# Line 504  class ClassGroupSingleton(ClassGroup): Line 451  class ClassGroupSingleton(ClassGroup):
451    
452          label -- a label for this group.          label -- a label for this group.
453          """          """
454          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label, props, group)
   
         self.prop = None  
         self.value = None  
455    
456          self.SetValue(value)          self.SetValue(value)
         self.SetProperties(prop)  
457    
458      def __copy__(self):      def __copy__(self):
459          return ClassGroupSingleton(self.GetValue(),          return ClassGroupSingleton(self.GetValue(),
# Line 518  class ClassGroupSingleton(ClassGroup): Line 461  class ClassGroupSingleton(ClassGroup):
461                                     self.GetLabel())                                     self.GetLabel())
462    
463      def __deepcopy__(self, memo):      def __deepcopy__(self, memo):
464          return ClassGroupSingleton(copy.copy(self.GetValue()),          return ClassGroupSingleton(self.GetValue(), group = self)
                                    copy.copy(self.GetProperties()),  
                                    copy.copy(self.GetLabel()))  
465    
466      def GetValue(self):      def GetValue(self):
467          """Return the associated value."""          """Return the associated value."""
468          return self.value          return self.__value
469    
470      def SetValue(self, value):      def SetValue(self, value):
471          """Associate this Group with the given value."""          """Associate this Group with the given value."""
472          self.value = value          self.__value = value
473    
474      def Matches(self, value):      def Matches(self, value):
475          """Determine if the given value matches the associated Group value."""          """Determine if the given value matches the associated Group value."""
476    
477          """Returns True if the value matches, False otherwise."""          """Returns True if the value matches, False otherwise."""
478    
479          return self.value == value          return self.__value == value
480    
481      def GetProperties(self):      def GetDisplayText(self):
482          """Return the Properties associated with this Group."""          label = self.GetLabel()
483    
484          return self.prop          if label != "": return label
485    
486      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  
487    
488      def __eq__(self, other):      def __eq__(self, other):
489          return isinstance(other, ClassGroupSingleton) \          return ClassGroup.__eq__(self, other) \
490              and self.GetProperties() == other.GetProperties() \              and isinstance(other, ClassGroupSingleton) \
491              and self.GetValue() == other.GetValue()              and self.__value == other.__value
492    
493      def __ne__(self, other):      def __repr__(self):
494          return not self.__eq__(other)          return "(" + repr(self.__value) + ", " + ClassGroup.__repr__(self) + ")"
495    
496  class ClassGroupDefault(ClassGroup):  class ClassGroupDefault(ClassGroup):
497      """The default Group. When values do not match any other      """The default Group. When values do not match any other
498         Group within a Classification, the properties from this         Group within a Classification, the properties from this
499         class are used."""         class are used."""
500    
501      def __init__(self, prop = None, label = ""):      def __init__(self, props = None, label = "", group = None):
502          """Constructor.          """Constructor.
503    
504          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 507  class ClassGroupDefault(ClassGroup):
507          label -- a label for this group.          label -- a label for this group.
508          """          """
509    
510          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label, props, group)
         self.SetProperties(prop)  
511    
512      def __copy__(self):      def __copy__(self):
513          return ClassGroupDefault(self.GetProperties(), self.GetLabel())          return ClassGroupDefault(self.GetProperties(), self.GetLabel())
514    
515      def __deepcopy__(self, memo):      def __deepcopy__(self, memo):
516          return ClassGroupDefault(copy.copy(self.GetProperties()),          return ClassGroupDefault(label = self.GetLabel(), group = self)
                                  copy.copy(self.GetLabel()))  
517    
518      def Matches(self, value):      def Matches(self, value):
519          return True          return True
520    
521      def GetProperties(self):      def GetDisplayText(self):
522          """Return the Properties associated with this Group."""          label = self.GetLabel()
         return self.prop  
523    
524      def SetProperties(self, prop):          if label != "": return label
         """Set the properties associated with this Group.  
525    
526          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  
527    
528      def __eq__(self, other):      def __eq__(self, other):
529          return isinstance(other, ClassGroupDefault) \          return ClassGroup.__eq__(self, other) \
530                and isinstance(other, ClassGroupDefault) \
531              and self.GetProperties() == other.GetProperties()              and self.GetProperties() == other.GetProperties()
532    
533      def __ne__(self, other):      def __repr__(self):
534          return not self.__eq__(other)          return "(" + ClassGroup.__repr__(self) + ")"
535    
536  class ClassGroupRange(ClassGroup):  class ClassGroupRange(ClassGroup):
537      """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
538         set of properties."""         set of properties."""
539    
540      def __init__(self, min = 0, max = 1, prop = None, label = ""):      def __init__(self, _range = (0,1), props = None, label = "", group=None):
541          """Constructor.          """Constructor.
542    
543          The minumum value must be strictly less than the maximum.          The minumum value must be strictly less than the maximum.
544    
545          min -- the minimum range value          _range -- either a tuple (min, max) where min < max or
546                      a Range object
         max -- the maximum range value  
547    
548          prop -- a ClassGroupProperites object. If prop is None a default          prop -- a ClassGroupProperites object. If prop is None a default
549                   set of properties is created.                   set of properties is created.
# Line 629  class ClassGroupRange(ClassGroup): Line 551  class ClassGroupRange(ClassGroup):
551          label -- a label for this group.          label -- a label for this group.
552          """          """
553    
554          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label, props, group)
555            self.SetRange(_range)
         self.min = self.max = 0  
         self.prop = None  
   
         self.SetRange(min, max)  
         self.SetProperties(prop)  
556    
557      def __copy__(self):      def __copy__(self):
558          return ClassGroupRange(self.GetMin(),          return ClassGroupRange(self.__range,
559                                 self.GetMax(),                                 props = self.GetProperties(),
560                                 self.GetProperties(),                                 label = self.GetLabel())
                                self.GetLabel())  
561    
562      def __deepcopy__(self, memo):      def __deepcopy__(self, memo):
563          return ClassGroupRange(copy.copy(self.GetMin()),          return ClassGroupRange(copy.copy(self.__range),
564                                 copy.copy(self.GetMax()),                                 group = self)
                                copy.copy(self.GetProperties()),  
                                copy.copy(self.GetLabel()))  
565    
566      def GetMin(self):      def GetMin(self):
567          """Return the range's minimum value."""          """Return the range's minimum value."""
568          return self.min          return self.__range.GetRange()[1]
569    
570      def SetMin(self, min):      def SetMin(self, min):
571          """Set the range's minimum value.          """Set the range's minimum value.
# Line 660  class ClassGroupRange(ClassGroup): Line 574  class ClassGroupRange(ClassGroup):
574                 maximum value. Use SetRange() to change both min and max values.                 maximum value. Use SetRange() to change both min and max values.
575          """          """
576            
577          self.SetRange(min, self.max)          self.SetRange((min, self.__range.GetRange()[2]))
578    
579      def GetMax(self):      def GetMax(self):
580          """Return the range's maximum value."""          """Return the range's maximum value."""
581          return self.max          return self.__range.GetRange()[2]
582    
583      def SetMax(self, max):      def SetMax(self, max):
584          """Set the range's maximum value.          """Set the range's maximum value.
# Line 672  class ClassGroupRange(ClassGroup): Line 586  class ClassGroupRange(ClassGroup):
586          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
587                 minimum value. Use SetRange() to change both min and max values.                 minimum value. Use SetRange() to change both min and max values.
588          """          """
589          self.SetRange(self.min, max)          self.SetRange((self.__range.GetRange()[1], max))
590    
591      def SetRange(self, min, max):      def SetRange(self, _range):
592          """Set a new range.          """Set a new range.
593    
594          Note that min must be strictly less than max.          _range -- Either a tuple (min, max) where min < max or
595                      a Range object.
596    
597          min -- the new minimum value          Raises ValueError on error.
         min -- the new maximum value  
598          """          """
599    
600          if min >= max:          if isinstance(_range, Range):
601              raise ValueError(_("ClassGroupRange: %i(min) >= %i(max)!") %              self.__range = _range
602                               (min, max))          elif isinstance(_range, types.TupleType) and len(_range) == 2:
603          self.min = min              self.__range = Range(("[", _range[0], _range[1], "["))
604          self.max = max          else:
605                raise ValueError()
606    
607      def GetRange(self):      def GetRange(self):
608          """Return the range as a tuple (min, max)"""          """Return the range as a string"""
609          return (self.min, self.max)          return self.__range.string(self.__range.GetRange())
610    
611      def Matches(self, value):      def Matches(self, value):
612          """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 614  class ClassGroupRange(ClassGroup):
614          The following check is used: min <= value < max.          The following check is used: min <= value < max.
615          """          """
616    
617          return self.min <= value < self.max          return operator.contains(self.__range, value)
618    
619      def GetProperties(self):      def GetDisplayText(self):
620          """Return the Properties associated with this Group."""          label = self.GetLabel()
         return self.prop  
621    
622      def SetProperties(self, prop):          if label != "": return label
         """Set the properties associated with this Group.  
623    
624          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  
625    
626      def __eq__(self, other):      def __eq__(self, other):
627          return isinstance(other, ClassGroupRange) \          return ClassGroup.__eq__(self, other) \
628              and self.GetProperties() == other.GetProperties() \              and isinstance(other, ClassGroupRange) \
629              and self.GetRange() == other.GetRange()              and self.__range == other.__range
630    
631      def __ne__(self, other):      def __repr__(self):
632          return not self.__eq__(other)          return "(" + str(self.__range) + ClassGroup.__repr__(self) + ")"
633    
634  class ClassGroupMap(ClassGroup):  class ClassGroupMap(ClassGroup):
635      """Currently, this class is not used."""      """Currently, this class is not used."""
# Line 746  class ClassGroupMap(ClassGroup): Line 654  class ClassGroupMap(ClassGroup):
654      def GetPropertiesFromValue(self, value):      def GetPropertiesFromValue(self, value):
655          pass          pass
656    
657        def GetDisplayText(self):
658            return "Map: " + self.map_type
659    
660      #      #
661      # built-in mappings      # built-in mappings
662      #      #

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26