/[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 602 by jonathan, Fri Apr 4 12:12:18 2003 UTC revision 1336 by jonathan, Tue Jul 1 16:09:26 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    
32  from Thuban import _  from Thuban.Model.color import Color, Transparent, Black
33  from Thuban.Model.color import Color  from Thuban.Model.range import Range
34    
35  import Thuban.Model.layer  import Thuban.Model.layer
36    
 # constants  
 RANGE_MIN  = 0  
 RANGE_MAX  = 1  
 RANGE_DATA = 2  
   
37  class Classification:  class Classification:
38      """Encapsulates the classification of layer. The Classification      """Encapsulates the classification of layer.
39      divides some kind of data into Groups which are associated with      
40      properties. Later the properties can be retrieved by matching      The Classification divides some kind of data into Groups which
41      data values to the appropriate group."""      are associated with properties. Later the properties can be
42        retrieved by matching data values to the appropriate group.
43        """
44    
45      def __init__(self, layer = None, field = None):      def __init__(self, layer = None, field = None):
46          """Initialize a classification.          """Initialize a classification.
47    
48             layer -- the Layer object who owns this classification          layer -- the Layer object who owns this classification
49    
50             field -- the name of the data table field that          field -- the name of the data table field that
51                      is to be used to classify layer properties                   is to be used to classify layer properties
52          """          """
53    
54          self.layer = None          self.layer = None
55          self.field = None          self.field = None
56          self.fieldType = None          self.fieldType = None
57          self.groups = []          self.__groups = []
58    
59          self.__setLayerLock = False          self.__setLayerLock = False
60    
61          self.SetDefaultGroup(ClassGroupDefault())          self.SetDefaultGroup(ClassGroupDefault())
62    
63          self.SetLayer(layer)          self.SetFieldInfo(field, None)
64          self.SetField(field)  
65            self._set_layer(layer)
66    
67      def __iter__(self):      def __iter__(self):
68          return ClassIterator(self.groups)          return ClassIterator(self.__groups)
69    
70        def __deepcopy__(self, memo):
71            clazz = Classification()
72    
73            # note: the only thing that isn't copied is the layer reference
74            clazz.field = self.field
75            clazz.fieldType = self.fieldType
76            clazz.__groups[0] = copy.deepcopy(self.__groups[0])
77    
78            for i in range(1, len(self.__groups)):
79                clazz.__groups.append(copy.deepcopy(self.__groups[i]))
80    
81            return clazz
82    
83      def __SendNotification(self):      def __SendNotification(self):
84          """Notify the layer that this class has changed."""          """Notify the layer that this class has changed."""
85          if self.layer is not None:          if self.layer is not None:
86              self.layer.ClassChanged()              self.layer.ClassChanged()
87            
     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()  
   
88      def GetField(self):      def GetField(self):
89          """Return the name of the field."""          """Return the name of the field."""
90          return self.field          return self.field
# Line 118  class Classification: Line 93  class Classification:
93          """Return the field type."""          """Return the field type."""
94          return self.fieldType          return self.fieldType
95    
96      def SetFieldType(self, type):      def SetFieldInfo(self, name, type):
97          """Set the type of the field used by this classification.          """Set the classified field name to 'name' and it's field
98            type to 'type'
99    
100            If this classification has an owning layer a ValueError
101            exception will be thrown either the field or field type
102            mismatch the information in the layer's table.
103    
104            If the field info is successful set and the class has
105            an owning layer, the layer will be informed that the
106            classification has changed.
107            """
108    
109            if name == "":
110                name = None
111    
112            if self.layer is None:
113                self.field = name
114                self.fieldType = type
115            elif name is None:
116                self.field = None
117                self.fieldType = None
118            else:
119                #
120                # verify that the field exists in the layer and that
121                # the type is correct.
122                #
123                fieldType = self.layer.GetFieldType(name)
124                if fieldType is None:
125                    raise ValueError("'%s' was not found in the layer's table."
126                                     % self.field)
127                elif type is not None and fieldType != type:
128                    raise ValueError("type doesn't match layer's field type for %s"
129                                     % self.field)
130    
131          A ValueError is raised if the owning layer is not None and              self.field = name
132          'type' is different from the current field type.              self.fieldType = fieldType
         """  
133    
134          if type != self.fieldType:          self.__SendNotification()
             if self.layer is not None:  
                 raise ValueError()  
             else:  
                 self.fieldType = type  
                 self.__SendNotification()  
135    
136      def SetLayer(self, layer):      def _set_layer(self, layer):
137          """Set the owning Layer of this classification.          """Internal: Set the owning Layer of this classification.
138    
139             A ValueError exception will be thrown either the field or          A ValueError exception will be thrown either the field or
140             field type mismatch the information in the layer's table.          field type mismatch the information in the layer's table.
         """  
   
         # prevent infinite recursion when calling SetClassification()  
         if self.__setLayerLock: return  
141    
142          self.__setLayerLock = True          If the layer is successful set, the layer will be informed
143            that the classification has changed.
144            """
145    
146          if layer is None:          if layer is None:
147              if self.layer is not None:              self.layer = None
                 l = self.layer  
                 self.layer = None  
                 l.SetClassification(None)  
148          else:          else:
             assert isinstance(layer, Thuban.Model.layer.Layer)  
   
149              old_layer = self.layer              old_layer = self.layer
   
150              self.layer = layer              self.layer = layer
151    
152              try:              try:
153                  self.SetField(self.GetField()) # this sync's the fieldType                  # this sync's the fieldType
154                    # and sends a notification to the layer
155                    self.SetFieldInfo(self.GetField(), None)
156              except ValueError:              except ValueError:
157                  self.layer = old_layer                  self.layer = old_layer
                 self.__setLayerLock = False  
158                  raise ValueError                  raise ValueError
             else:  
                 self.layer.SetClassification(self)  
   
         self.__setLayerLock = False  
159    
160      def GetLayer(self):      def GetLayer(self):
161          """Return the parent layer."""          """Return the parent layer."""
162          return self.layer          return self.layer
163    
     def SetDefaultGroup(self, group):  
         """Set the group to be used when a value can't be classified.  
   
            group -- group that the value maps to.  
         """  
   
         assert isinstance(group, ClassGroupDefault)  
         self.AddGroup(group)  
   
     def GetDefaultGroup(self):  
         """Return the default group."""  
         return self.groups[0]  
   
164      #      #
165      # these SetDefault* methods are really only provided for      # these SetDefault* methods are really only provided for
166      # some backward compatibility. they should be considered      # some backward compatibility. they should be considered
# Line 195  class Classification: Line 172  class Classification:
172    
173          fill -- a Color object.          fill -- a Color object.
174          """          """
         assert isinstance(fill, Color)  
175          self.GetDefaultGroup().GetProperties().SetFill(fill)          self.GetDefaultGroup().GetProperties().SetFill(fill)
176          self.__SendNotification()          self.__SendNotification()
177                    
# Line 208  class Classification: Line 184  class Classification:
184    
185          color -- a Color object.          color -- a Color object.
186          """          """
         assert isinstance(color, Color)  
187          self.GetDefaultGroup().GetProperties().SetLineColor(color)          self.GetDefaultGroup().GetProperties().SetLineColor(color)
188          self.__SendNotification()          self.__SendNotification()
189                    
# Line 221  class Classification: Line 196  class Classification:
196    
197          lineWidth -- an integer > 0.          lineWidth -- an integer > 0.
198          """          """
199          assert isinstance(lineWidth, IntType)          assert isinstance(lineWidth, types.IntType)
200          self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)          self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)
201          self.__SendNotification()          self.__SendNotification()
202                    
# Line 229  class Classification: Line 204  class Classification:
204          """Return the default line width."""          """Return the default line width."""
205          return self.GetDefaultGroup().GetProperties().GetLineWidth()          return self.GetDefaultGroup().GetProperties().GetLineWidth()
206                    
207      def AddGroup(self, item):  
208          """Add a new ClassGroup item to the classification.      #
209        # The methods that manipulate self.__groups have to be kept in
210        # sync. We store the default group in index 0 to make it
211        # convienent to iterate over the classification's groups, but
212        # from the user's perspective the first (non-default) group is
213        # at index 0 and the DefaultGroup is a special entity.
214        #
215    
216        def SetDefaultGroup(self, group):
217            """Set the group to be used when a value can't be classified.
218    
219            group -- group that the value maps to.
220            """
221    
222            assert isinstance(group, ClassGroupDefault)
223            if len(self.__groups) > 0:
224                self.__groups[0] = group
225            else:
226                self.__groups.append(group)
227    
228        def GetDefaultGroup(self):
229            """Return the default group."""
230            return self.__groups[0]
231    
232        def AppendGroup(self, item):
233            """Append a new ClassGroup item to the classification.
234    
235          item -- this must be a valid ClassGroup object          item -- this must be a valid ClassGroup object
236          """          """
237    
238          assert isinstance(item, ClassGroup)          self.InsertGroup(self.GetNumGroups(), item)
239    
240          if len(self.groups) > 0 and isinstance(item, ClassGroupDefault):      def InsertGroup(self, index, group):
241              self.groups[0] = item          
242          else:          assert isinstance(group, ClassGroup)
243              self.groups.append(item)  
244            self.__groups.insert(index + 1, group)
245    
246            self.__SendNotification()
247    
248        def RemoveGroup(self, index):
249            return self.__groups.pop(index + 1)
250    
251        def ReplaceGroup(self, index, group):
252            assert isinstance(group, ClassGroup)
253    
254            self.__groups[index + 1] = group
255    
256          self.__SendNotification()          self.__SendNotification()
257    
258      def GetGroup(self, value):      def GetGroup(self, index):
259            return self.__groups[index + 1]
260    
261        def GetNumGroups(self):
262            """Return the number of non-default groups in the classification."""
263            return len(self.__groups) - 1
264    
265    
266        def FindGroup(self, value):
267          """Return the associated group, or the default group.          """Return the associated group, or the default group.
268    
269             Groups are checked in the order the were added to the          Groups are checked in the order the were added to the
270             Classification.          Classification.
271    
272             value -- the value to classify. If there is no mapping,          value -- the value to classify. If there is no mapping,
273                      the field is None or value is None,                   the field is None or value is None,
274                      return the default properties                   return the default properties
275          """          """
276    
277          if self.GetField() is not None and value is not None:          if self.GetField() is not None and value is not None:
278    
279              for i in range(1, len(self.groups)):              for i in range(1, len(self.__groups)):
280                  group = self.groups[i]                  group = self.__groups[i]
281                  if group.Matches(value):                  if group.Matches(value):
282                      return group                      return group
283    
284          return self.GetDefaultGroup()          return self.GetDefaultGroup()
285    
286      def GetProperties(self, value):      def GetProperties(self, value):
287          """Return the properties associated with the given value."""          """Return the properties associated with the given value.
288          
289            Use this function rather than Classification.FindGroup().GetProperties()
290            since the returned group may be a ClassGroupMap which doesn't support
291            a call to GetProperties().
292            """
293    
294          group = self.GetGroup(value)          group = self.FindGroup(value)
295          if isinstance(group, ClassGroupMap):          if isinstance(group, ClassGroupMap):
296              return group.GetPropertiesFromValue(value)              return group.GetPropertiesFromValue(value)
297          else:          else:
# Line 277  class Classification: Line 301  class Classification:
301          items = []          items = []
302    
303          def build_color_item(text, color):          def build_color_item(text, color):
304              if color is Color.None:              if color is Transparent:
305                  return ("%s: %s" % (text, _("None")), None)                  return ("%s: %s" % (text, _("None")), None)
306    
307              return ("%s: (%.3f, %.3f, %.3f)" %              return ("%s: (%.3f, %.3f, %.3f)" %
# Line 302  class Classification: Line 326  class Classification:
326              return (label, i)              return (label, i)
327    
328          for p in self:          for p in self:
329              if isinstance(p, ClassGroupDefault):              items.append(build_item(p, p.GetDisplayText()))
330                  items.append(build_item(self.GetDefaultGroup(), _("'DEFAULT'")))  
331              elif isinstance(p, ClassGroupSingleton):  #           if isinstance(p, ClassGroupDefault):
332                  items.append(build_item(p, str(p.GetValue())))  #               items.append(build_item(self.GetDefaultGroup(), _("'DEFAULT'")))
333              elif isinstance(p, ClassGroupRange):  #           elif isinstance(p, ClassGroupSingleton):
334                  items.append(build_item(p, "%s - %s" %  #               items.append(build_item(p, str(p.GetValue())))
335                                             (p.GetMin(), p.GetMax())))  #           elif isinstance(p, ClassGroupRange):
336    #               items.append(build_item(p, "%s - %s" %
337    #                                          (p.GetMin(), p.GetMax())))
338    
339          return (_("Classification"), items)          return (_("Classification"), items)
340    
# Line 372  class ClassGroupProperties: Line 398  class ClassGroupProperties:
398    
399          props -- a ClassGroupProperties object. The class is copied if          props -- a ClassGroupProperties object. The class is copied if
400                   prop is not None. Otherwise, a default set of properties                   prop is not None. Otherwise, a default set of properties
401                   is created such that: line color = Color.Black, line width = 1,                   is created such that: line color = Black, line width = 1,
402                   and fill color = Color.None                   and fill color = Transparent
403          """          """
404    
405          self.stroke = None          #self.stroke = None
406          self.strokeWidth = 0          #self.strokeWidth = 0
407          self.fill = None          #self.fill = None
408    
409          if props is not None:          if props is not None:
410              self.SetProperties(props)              self.SetProperties(props)
411          else:          else:
412              self.SetLineColor(Color.Black)              self.SetLineColor(Black)
413              self.SetLineWidth(1)              self.SetLineWidth(1)
414              self.SetFill(Color.None)              self.SetFill(Transparent)
415    
416      def SetProperties(self, props):      def SetProperties(self, props):
417          """Set this class's properties to those in class props."""          """Set this class's properties to those in class props."""
# Line 397  class ClassGroupProperties: Line 423  class ClassGroupProperties:
423                    
424      def GetLineColor(self):      def GetLineColor(self):
425          """Return the line color as a Color object."""          """Return the line color as a Color object."""
426          return self.stroke          return self.__stroke
427    
428      def SetLineColor(self, color):      def SetLineColor(self, color):
429          """Set the line color.          """Set the line color.
# Line 405  class ClassGroupProperties: Line 431  class ClassGroupProperties:
431          color -- the color of the line. This must be a Color object.          color -- the color of the line. This must be a Color object.
432          """          """
433    
434          assert isinstance(color, Color)          self.__stroke = color
         #self.stroke = Color(color.red, color.green, color.blue)  
         self.stroke = copy.copy(color)  
435    
436      def GetLineWidth(self):      def GetLineWidth(self):
437          """Return the line width."""          """Return the line width."""
438          return self.strokeWidth          return self.__strokeWidth
439    
440      def SetLineWidth(self, lineWidth):      def SetLineWidth(self, lineWidth):
441          """Set the line width.          """Set the line width.
442    
443          lineWidth -- the new line width. This must be > 0.          lineWidth -- the new line width. This must be > 0.
444          """          """
445          assert isinstance(lineWidth, IntType)          assert isinstance(lineWidth, types.IntType)
446          if (lineWidth < 1):          if (lineWidth < 1):
447              raise ValueError(_("lineWidth < 1"))              raise ValueError(_("lineWidth < 1"))
448    
449          self.strokeWidth = lineWidth          self.__strokeWidth = lineWidth
450    
451      def GetFill(self):      def GetFill(self):
452          """Return the fill color as a Color object."""          """Return the fill color as a Color object."""
453          return self.fill          return self.__fill
454    
455      def SetFill(self, fill):      def SetFill(self, fill):
456          """Set the fill color.          """Set the fill color.
# Line 434  class ClassGroupProperties: Line 458  class ClassGroupProperties:
458          fill -- the color of the fill. This must be a Color object.          fill -- the color of the fill. This must be a Color object.
459          """          """
460    
461          assert isinstance(fill, Color)          self.__fill = fill
         self.fill = copy.copy(fill)  
         #self.fill = Color(fill.red, fill.green, fill.blue)  
462    
463      def __eq__(self, other):      def __eq__(self, other):
464          """Return true if 'props' has the same attributes as this class"""          """Return true if 'props' has the same attributes as this class"""
465    
466            #
467            # using 'is' over '==' results in a huge performance gain
468            # in the renderer
469            #
470          return isinstance(other, ClassGroupProperties)   \          return isinstance(other, ClassGroupProperties)   \
471              and self.stroke      == other.GetLineColor() \              and (self.__stroke is other.__stroke or      \
472              and self.strokeWidth == other.GetLineWidth() \                   self.__stroke == other.__stroke)        \
473              and self.fill        == other.GetFill()              and (self.__fill is other.__fill or          \
474                     self.__fill == other.__fill)            \
475                and self.__strokeWidth == other.__strokeWidth
476    
477      def __ne__(self, other):      def __ne__(self, other):
478          return not self.__eq__(other)          return not self.__eq__(other)
# Line 455  class ClassGroupProperties: Line 483  class ClassGroupProperties:
483      def __deepcopy__(self):      def __deepcopy__(self):
484          return ClassGroupProperties(self)          return ClassGroupProperties(self)
485    
486        def __repr__(self):
487            return repr((self.__stroke, self.__strokeWidth, self.__fill))
488    
489  class ClassGroup:  class ClassGroup:
490      """A base class for all Groups within a Classification"""      """A base class for all Groups within a Classification"""
491    
492      def __init__(self, label = ""):      def __init__(self, label = "", props = None, group = None):
493          """Constructor.          """Constructor.
494    
495          label -- A string representing the Group's label          label -- A string representing the Group's label
496          """          """
497    
498          self.label = None          if group is not None:
499                self.SetLabel(copy.copy(group.GetLabel()))
500          self.SetLabel(label)              self.SetProperties(copy.copy(group.GetProperties()))
501                self.SetVisible(group.IsVisible())
502            else:
503                self.SetLabel(label)
504                self.SetProperties(props)
505                self.SetVisible(True)
506    
507      def GetLabel(self):      def GetLabel(self):
508          """Return the Group's label."""          """Return the Group's label."""
# Line 478  class ClassGroup: Line 514  class ClassGroup:
514          label -- a string representing the Group's label. This must          label -- a string representing the Group's label. This must
515                   not be None.                   not be None.
516          """          """
517          assert isinstance(label, StringType)          assert isinstance(label, types.StringTypes)
518          self.label = label          self.label = label
519    
520      def GetDisplayText(self):      def GetDisplayText(self):
# Line 494  class ClassGroup: Line 530  class ClassGroup:
530          return False          return False
531    
532      def GetProperties(self):      def GetProperties(self):
533          """Return the properties associated with the given value.          """Return the properties associated with the given value."""
534    
535          Returns None. This needs to be overridden by all subclasses.          return self.prop
         """  
         assert False, "GetProperties must be overridden by subclass!"  
         return None  
536    
537        def SetProperties(self, prop):
538            """Set the properties associated with this Group.
539    
540            prop -- a ClassGroupProperties object. if prop is None,
541                    a default set of properties is created.
542            """
543    
544            if prop is None: prop = ClassGroupProperties()
545            assert isinstance(prop, ClassGroupProperties)
546            self.prop = prop
547    
548        def IsVisible(self):
549            return self.visible
550    
551        def SetVisible(self, visible):
552            self.visible = visible
553    
554        def __eq__(self, other):
555            return isinstance(other, ClassGroup) \
556                and self.label == other.label \
557                and self.GetProperties() == other.GetProperties()
558    
559        def __ne__(self, other):
560            return not self.__eq__(other)
561    
562        def __repr__(self):
563            return repr(self.label) + ", " + repr(self.GetProperties())
564            
565  class ClassGroupSingleton(ClassGroup):  class ClassGroupSingleton(ClassGroup):
566      """A Group that is associated with a single value."""      """A Group that is associated with a single value."""
567    
568      def __init__(self, value = 0, prop = None, label = ""):      def __init__(self, value = 0, props = None, label = "", group = None):
569          """Constructor.          """Constructor.
570    
571          value -- the associated value.          value -- the associated value.
# Line 515  class ClassGroupSingleton(ClassGroup): Line 575  class ClassGroupSingleton(ClassGroup):
575    
576          label -- a label for this group.          label -- a label for this group.
577          """          """
578          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label, props, group)
   
         self.prop = None  
         self.value = None  
579    
580          self.SetValue(value)          self.SetValue(value)
         self.SetProperties(prop)  
581    
582      def __copy__(self):      def __copy__(self):
583          return ClassGroupSingleton(self.GetValue(),          return ClassGroupSingleton(self.GetValue(),
# Line 529  class ClassGroupSingleton(ClassGroup): Line 585  class ClassGroupSingleton(ClassGroup):
585                                     self.GetLabel())                                     self.GetLabel())
586    
587      def __deepcopy__(self, memo):      def __deepcopy__(self, memo):
588          return ClassGroupSingleton(copy.copy(self.GetValue()),          return ClassGroupSingleton(self.GetValue(), group = self)
                                    copy.copy(self.GetProperties()),  
                                    copy.copy(self.GetLabel()))  
589    
590      def GetValue(self):      def GetValue(self):
591          """Return the associated value."""          """Return the associated value."""
592          return self.value          return self.__value
593    
594      def SetValue(self, value):      def SetValue(self, value):
595          """Associate this Group with the given value."""          """Associate this Group with the given value."""
596          self.value = value          self.__value = value
597    
598      def Matches(self, value):      def Matches(self, value):
599          """Determine if the given value matches the associated Group value."""          """Determine if the given value matches the associated Group value."""
600    
601          """Returns True if the value matches, False otherwise."""          """Returns True if the value matches, False otherwise."""
602    
603          return self.value == value          return self.__value == value
   
     def GetProperties(self):  
         """Return the Properties associated with this Group."""  
   
         return self.prop  
   
     def SetProperties(self, prop):  
         """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  
604    
605      def GetDisplayText(self):      def GetDisplayText(self):
606          label = self.GetLabel()          label = self.GetLabel()
# Line 572  class ClassGroupSingleton(ClassGroup): Line 610  class ClassGroupSingleton(ClassGroup):
610          return str(self.GetValue())          return str(self.GetValue())
611    
612      def __eq__(self, other):      def __eq__(self, other):
613          return isinstance(other, ClassGroupSingleton) \          return ClassGroup.__eq__(self, other) \
614              and self.GetProperties() == other.GetProperties() \              and isinstance(other, ClassGroupSingleton) \
615              and self.GetValue() == other.GetValue()              and self.__value == other.__value
616    
617      def __ne__(self, other):      def __repr__(self):
618          return not self.__eq__(other)          return "(" + repr(self.__value) + ", " + ClassGroup.__repr__(self) + ")"
619    
620  class ClassGroupDefault(ClassGroup):  class ClassGroupDefault(ClassGroup):
621      """The default Group. When values do not match any other      """The default Group. When values do not match any other
622         Group within a Classification, the properties from this         Group within a Classification, the properties from this
623         class are used."""         class are used."""
624    
625      def __init__(self, prop = None, label = ""):      def __init__(self, props = None, label = "", group = None):
626          """Constructor.          """Constructor.
627    
628          prop -- a ClassGroupProperites object. If prop is None a default          prop -- a ClassGroupProperites object. If prop is None a default
# Line 593  class ClassGroupDefault(ClassGroup): Line 631  class ClassGroupDefault(ClassGroup):
631          label -- a label for this group.          label -- a label for this group.
632          """          """
633    
634          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label, props, group)
         self.SetProperties(prop)  
635    
636      def __copy__(self):      def __copy__(self):
637          return ClassGroupDefault(self.GetProperties(), self.GetLabel())          return ClassGroupDefault(self.GetProperties(), self.GetLabel())
638    
639      def __deepcopy__(self, memo):      def __deepcopy__(self, memo):
640          return ClassGroupDefault(copy.copy(self.GetProperties()),          return ClassGroupDefault(label = self.GetLabel(), group = self)
                                  copy.copy(self.GetLabel()))  
641    
642      def Matches(self, value):      def Matches(self, value):
643          return True          return True
644    
     def GetProperties(self):  
         """Return the Properties associated with this Group."""  
         return self.prop  
   
     def SetProperties(self, prop):  
         """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  
   
645      def GetDisplayText(self):      def GetDisplayText(self):
646          label = self.GetLabel()          label = self.GetLabel()
647    
648          if label != "": return label          if label != "": return label
649    
650          return "DEFAULT"          return _("DEFAULT")
651    
652      def __eq__(self, other):      def __eq__(self, other):
653          return isinstance(other, ClassGroupDefault) \          return ClassGroup.__eq__(self, other) \
654                and isinstance(other, ClassGroupDefault) \
655              and self.GetProperties() == other.GetProperties()              and self.GetProperties() == other.GetProperties()
656    
657      def __ne__(self, other):      def __repr__(self):
658          return not self.__eq__(other)          return "(" + ClassGroup.__repr__(self) + ")"
659    
660  class ClassGroupRange(ClassGroup):  class ClassGroupRange(ClassGroup):
661      """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
662         set of properties."""         set of properties."""
663    
664      def __init__(self, min = 0, max = 1, prop = None, label = ""):      def __init__(self, min = 0, max = 1, props = None, label = "", group=None):
665          """Constructor.          """Constructor.
666    
667          The minumum value must be strictly less than the maximum.          The minumum value must be strictly less than the maximum.
# Line 654  class ClassGroupRange(ClassGroup): Line 676  class ClassGroupRange(ClassGroup):
676          label -- a label for this group.          label -- a label for this group.
677          """          """
678    
679          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label, props, group)
   
         self.min = self.max = 0  
         self.prop = None  
680    
681            #self.__min = self.__max = 0
682            #self.__range = Range("[" + repr(float(min)) + ";" +
683                                       #repr(float(max)) + "[")
684          self.SetRange(min, max)          self.SetRange(min, max)
         self.SetProperties(prop)  
685    
686      def __copy__(self):      def __copy__(self):
687          return ClassGroupRange(self.GetMin(),          return ClassGroupRange(min = self.__range,
688                                 self.GetMax(),                                 max = None,
689                                 self.GetProperties(),                                 props = self.GetProperties(),
690                                 self.GetLabel())                                 label = self.GetLabel())
691    
692      def __deepcopy__(self, memo):      def __deepcopy__(self, memo):
693          return ClassGroupRange(copy.copy(self.GetMin()),          return ClassGroupRange(min = copy.copy(self.__range),
694                                 copy.copy(self.GetMax()),                                 max = copy.copy(self.GetMax()),
695                                 copy.copy(self.GetProperties()),                                 group = self)
                                copy.copy(self.GetLabel()))  
696    
697      def GetMin(self):      def GetMin(self):
698          """Return the range's minimum value."""          """Return the range's minimum value."""
699          return self.min          return self.__range.GetRange()[1]
700    
701      def SetMin(self, min):      def SetMin(self, min):
702          """Set the range's minimum value.          """Set the range's minimum value.
# Line 685  class ClassGroupRange(ClassGroup): Line 705  class ClassGroupRange(ClassGroup):
705                 maximum value. Use SetRange() to change both min and max values.                 maximum value. Use SetRange() to change both min and max values.
706          """          """
707            
708          self.SetRange(min, self.max)          self.SetRange(min, self.__range.GetRange()[2])
709    
710      def GetMax(self):      def GetMax(self):
711          """Return the range's maximum value."""          """Return the range's maximum value."""
712          return self.max          return self.__range.GetRange()[2]
713    
714      def SetMax(self, max):      def SetMax(self, max):
715          """Set the range's maximum value.          """Set the range's maximum value.
# Line 697  class ClassGroupRange(ClassGroup): Line 717  class ClassGroupRange(ClassGroup):
717          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
718                 minimum value. Use SetRange() to change both min and max values.                 minimum value. Use SetRange() to change both min and max values.
719          """          """
720          self.SetRange(self.min, max)          self.SetRange(self.__range.GetRange()[1], max)
721    
722      def SetRange(self, min, max):      def SetRange(self, min, max = None):
723          """Set a new range.          """Set a new range.
724    
725          Note that min must be strictly less than max.          Note that min must be strictly less than max.
# Line 708  class ClassGroupRange(ClassGroup): Line 728  class ClassGroupRange(ClassGroup):
728          min -- the new maximum value          min -- the new maximum value
729          """          """
730    
731          if min >= max:          if isinstance(min, Range):
732              raise ValueError(_("ClassGroupRange: %i(min) >= %i(max)!") %              self.__range = min
733                               (min, max))          else:
734          self.min = min              if max is None:
735          self.max = max                  raise ValueError()
736    
737                self.__range = Range(("[", min, max, "["))
738    
739      def GetRange(self):      def GetRange(self):
740          """Return the range as a tuple (min, max)"""          """Return the range as a string"""
741          return (self.min, self.max)          #return (self.__min, self.__max)
742            return self.__range.string(self.__range.GetRange())
743    
744      def Matches(self, value):      def Matches(self, value):
745          """Determine if the given value lies with the current range.          """Determine if the given value lies with the current range.
# Line 724  class ClassGroupRange(ClassGroup): Line 747  class ClassGroupRange(ClassGroup):
747          The following check is used: min <= value < max.          The following check is used: min <= value < max.
748          """          """
749    
750          return self.min <= value < self.max          return operator.contains(self.__range, value)
751            #return self.__min <= value < self.__max
     def GetProperties(self):  
         """Return the Properties associated with this Group."""  
         return self.prop  
   
     def SetProperties(self, prop):  
         """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  
752    
753      def GetDisplayText(self):      def GetDisplayText(self):
754          label = self.GetLabel()          label = self.GetLabel()
755    
756          if label != "": return label          if label != "": return label
757    
758          return _("%s - %s") % (self.GetMin(), self.GetMax())          #return _("%s - %s") % (self.GetMin(), self.GetMax())
759            #return repr(self.__range)
760            return self.__range.string(self.__range.GetRange())
761    
762      def __eq__(self, other):      def __eq__(self, other):
763          return isinstance(other, ClassGroupRange) \          return ClassGroup.__eq__(self, other) \
764              and self.GetProperties() == other.GetProperties() \              and isinstance(other, ClassGroupRange) \
765              and self.GetRange() == other.GetRange()              and self.__range == other.__range
766                #and self.__min == other.__min \
767      def __ne__(self, other):              #and self.__max == other.__max
768          return not self.__eq__(other)  
769        def __repr__(self):
770            return "(" + str(self.__range) + ClassGroup.__repr__(self) + ")"
771            #return "(" + repr(self.__min) + ", " + repr(self.__max) + ", " + \
772                   #ClassGroup.__repr__(self) + ")"
773    
774  class ClassGroupMap(ClassGroup):  class ClassGroupMap(ClassGroup):
775      """Currently, this class is not used."""      """Currently, this class is not used."""

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26