/[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 462 by jonathan, Wed Mar 5 18:17:17 2003 UTC revision 1249 by jonathan, Fri Jun 20 09:27:19 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  from types import *  from Thuban 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    
 from Thuban import _  
32  from Thuban.Model.color import Color  from Thuban.Model.color import Color
33    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          self.__sendMessages = False  
59            self.__setLayerLock = False
60    
         self.__ToggleMessages(False)  
61          self.SetDefaultGroup(ClassGroupDefault())          self.SetDefaultGroup(ClassGroupDefault())
62    
63          self.SetLayer(layer)          self.SetLayer(layer)
64          self.SetField(field)          self.SetField(field)
65    
         self.__ToggleMessages(True)  
   
66      def __iter__(self):      def __iter__(self):
67          return ClassIterator(self.groups)          return ClassIterator(self.__groups)
68    
69      def __ToggleMessages(self, on):      def __deepcopy__(self, memo):
70          self.__sendMessages = on          clazz = Classification()
71    
72      def __SendMessage(self, message):          # note: the only thing that isn't copied is the layer reference
73          """Send the message 'message' to the parent layer."""          clazz.field = self.field
74          if self.__sendMessages and self.layer is not None:          clazz.fieldType = self.fieldType
75              self.layer.changed(message, self.layer)          clazz.__groups[0] = copy.deepcopy(self.__groups[0])
76    
77            for i in range(1, len(self.__groups)):
78                clazz.__groups.append(copy.deepcopy(self.__groups[i]))
79    
80            return clazz
81    
82        def __SendNotification(self):
83            """Notify the layer that this class has changed."""
84            if self.layer is not None:
85                self.layer.ClassChanged()
86            
87      def SetField(self, field = None):      def SetField(self, field):
88          """Set the name of the data table field to use.          """Set the name of the data table field to use.
89                    
90             field -- if None then all values map to the default data          If there is no layer then the field type is set to None,
91            otherwise the layer is queried to find the type of the
92            field data
93    
94            field -- if None then all values map to the default data
95          """          """
96    
97          if field == "":          if field == "":
98              field = None              field = None
99    
         self.field = field  
100    
101          if self.layer is not None:          if field is None:
102              fieldType = self.layer.GetFieldType(field)              if self.layer is not None:
103                    self.fieldType = None
104          else:          else:
105              fieldType = None              if self.layer is not None:
106                    fieldType = self.layer.GetFieldType(field)
107          self.SetFieldType(fieldType)                  if fieldType is None:
108                        raise ValueError("'%s' was not found in the layer's table."
109                                         % self.field)
110    
111                    #
112                    # unfortunately we cannot call SetFieldType() because it
113                    # requires the layer to be None
114                    #
115                    self.fieldType = fieldType
116                    #self.SetFieldType(fieldType)
117    
118          # XXX: if fieldType comes back None then field isn't in the table!          self.field = field
119    
120          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendNotification()
121    
122      def GetField(self):      def GetField(self):
123          """Return the name of the field."""          """Return the name of the field."""
# Line 109  class Classification: Line 128  class Classification:
128          return self.fieldType          return self.fieldType
129    
130      def SetFieldType(self, type):      def SetFieldType(self, type):
131          self.fieldType = type          """Set the type of the field used by this classification.
132    
133            A ValueError is raised if the owning layer is not None and
134            'type' is different from the current field type.
135            """
136    
137            if type != self.fieldType:
138                if self.layer is not None:
139                    raise ValueError()
140                else:
141                    self.fieldType = type
142                    self.__SendNotification()
143    
144      def SetLayer(self, layer):      def SetLayer(self, layer):
145          """Set the owning Layer of this classification."""          """Set the owning Layer of this classification.
146    
147            A ValueError exception will be thrown either the field or
148            field type mismatch the information in the layer's table.
149            """
150    
151          if __debug__:          # prevent infinite recursion when calling SetClassification()
152              if layer is not None:          if self.__setLayerLock: return
                 assert(isinstance(layer, Thuban.Model.layer.Layer))  
153    
154          self.layer = layer          self.__setLayerLock = True
         self.SetField(self.GetField()) # XXX: this sync's the fieldType  
155    
156          self.__SendMessage(LAYER_LEGEND_CHANGED)          if layer is None:
157                if self.layer is not None:
158                    l = self.layer
159                    self.layer = None
160                    l.SetClassification(None)
161            else:
162                assert isinstance(layer, Thuban.Model.layer.Layer)
163    
164      def GetLayer(self):              old_layer = self.layer
         """Return the parent layer."""  
         return self.layer  
165    
166      def SetDefaultGroup(self, group):              self.layer = layer
         """Set the group to be used when a value can't be classified.  
167    
168             group -- group that the value maps to.              try:
169          """                  self.SetField(self.GetField()) # this sync's the fieldType
170                except ValueError:
171                    self.layer = old_layer
172                    self.__setLayerLock = False
173                    raise ValueError
174                else:
175                    self.layer.SetClassification(self)
176    
177          assert(isinstance(group, ClassGroupDefault))          self.__setLayerLock = False
178          self.AddGroup(group)  
179        def GetLayer(self):
180            """Return the parent layer."""
181            return self.layer
182    
     def GetDefaultGroup(self):  
         """Return the default group."""  
         return self.groups[0]  
183    
184      #      #
185      # these SetDefault* methods are really only provided for      # these SetDefault* methods are really only provided for
# Line 151  class Classification: Line 192  class Classification:
192    
193          fill -- a Color object.          fill -- a Color object.
194          """          """
         assert(isinstance(fill, Color))  
195          self.GetDefaultGroup().GetProperties().SetFill(fill)          self.GetDefaultGroup().GetProperties().SetFill(fill)
196          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendNotification()
197                    
198      def GetDefaultFill(self):      def GetDefaultFill(self):
199          """Return the default fill color."""          """Return the default fill color."""
# Line 164  class Classification: Line 204  class Classification:
204    
205          color -- a Color object.          color -- a Color object.
206          """          """
         assert(isinstance(color, Color))  
207          self.GetDefaultGroup().GetProperties().SetLineColor(color)          self.GetDefaultGroup().GetProperties().SetLineColor(color)
208          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendNotification()
209                    
210      def GetDefaultLineColor(self):      def GetDefaultLineColor(self):
211          """Return the default line color."""          """Return the default line color."""
# Line 177  class Classification: Line 216  class Classification:
216    
217          lineWidth -- an integer > 0.          lineWidth -- an integer > 0.
218          """          """
219          assert(isinstance(lineWidth, IntType))          assert isinstance(lineWidth, types.IntType)
220          self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)          self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)
221          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendNotification()
222                    
223      def GetDefaultLineWidth(self):      def GetDefaultLineWidth(self):
224          """Return the default line width."""          """Return the default line width."""
225          return self.GetDefaultGroup().GetProperties().GetLineWidth()          return self.GetDefaultGroup().GetProperties().GetLineWidth()
226                    
227      def AddGroup(self, item):  
228          """Add a new ClassGroup item to the classification.      #
229        # The methods that manipulate self.__groups have to be kept in
230        # sync. We store the default group in index 0 to make it
231        # convienent to iterate over the classification's groups, but
232        # from the user's perspective the first (non-default) group is
233        # at index 0 and the DefaultGroup is a special entity.
234        #
235    
236        def SetDefaultGroup(self, group):
237            """Set the group to be used when a value can't be classified.
238    
239            group -- group that the value maps to.
240            """
241    
242            assert isinstance(group, ClassGroupDefault)
243            if len(self.__groups) > 0:
244                self.__groups[0] = group
245            else:
246                self.__groups.append(group)
247    
248        def GetDefaultGroup(self):
249            """Return the default group."""
250            return self.__groups[0]
251    
252        def AppendGroup(self, item):
253            """Append a new ClassGroup item to the classification.
254    
255          item -- this must be a valid ClassGroup object          item -- this must be a valid ClassGroup object
256          """          """
257    
258          assert(isinstance(item, ClassGroup))          self.InsertGroup(self.GetNumGroups(), item)
259    
260          if len(self.groups) > 0 and isinstance(item, ClassGroupDefault):      def InsertGroup(self, index, group):
261              self.groups[0] = item          
262              #self.SetDefaultGroup(item)          assert isinstance(group, ClassGroup)
263          else:  
264              self.groups.append(item)          self.__groups.insert(index + 1, group)
265    
266            self.__SendNotification()
267    
268        def RemoveGroup(self, index):
269            return self.__groups.pop(index + 1)
270    
271        def ReplaceGroup(self, index, group):
272            assert isinstance(group, ClassGroup)
273    
274          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__groups[index + 1] = group
275    
276      def GetGroup(self, value):          self.__SendNotification()
277    
278        def GetGroup(self, index):
279            return self.__groups[index + 1]
280    
281        def GetNumGroups(self):
282            """Return the number of non-default groups in the classification."""
283            return len(self.__groups) - 1
284    
285    
286        def FindGroup(self, value):
287          """Return the associated group, or the default group.          """Return the associated group, or the default group.
288    
289             Groups are checked in the order the were added to the          Groups are checked in the order the were added to the
290             Classification.          Classification.
291    
292             value -- the value to classify. If there is no mapping,          value -- the value to classify. If there is no mapping,
293                      or value is None, return the default properties                   the field is None or value is None,
294                     return the default properties
295          """          """
296    
297          if self.field is not None and value is not None:          if self.GetField() is not None and value is not None:
298    
299              for i in range(1, len(self.groups)):              for i in range(1, len(self.__groups)):
300                  group = self.groups[i]                  group = self.__groups[i]
301                  if group.Matches(value):                  if group.Matches(value):
302                      return group                      return group
303    
304          return self.GetDefaultGroup()          return self.GetDefaultGroup()
305    
306      def GetProperties(self, value):      def GetProperties(self, value):
307          """Return the properties associated with the given value."""          """Return the properties associated with the given value.
308          
309            Use this function rather than Classification.FindGroup().GetProperties()
310            since the returned group may be a ClassGroupMap which doesn't support
311            a call to GetProperties().
312            """
313    
314          group = self.GetGroup(value)          group = self.FindGroup(value)
315          if isinstance(group, ClassGroupMap):          if isinstance(group, ClassGroupMap):
316              return group.GetPropertiesFromValue(value)              return group.GetPropertiesFromValue(value)
317          else:          else:
# Line 233  class Classification: Line 321  class Classification:
321          items = []          items = []
322    
323          def build_color_item(text, color):          def build_color_item(text, color):
324              if color is Color.None:              if color is Color.Transparent:
325                  return ("%s: %s" % (text, _("None")), None)                  return ("%s: %s" % (text, _("None")), None)
326    
327              return ("%s: (%.3f, %.3f, %.3f)" %              return ("%s: (%.3f, %.3f, %.3f)" %
# Line 258  class Classification: Line 346  class Classification:
346              return (label, i)              return (label, i)
347    
348          for p in self:          for p in self:
349              if isinstance(p, ClassGroupDefault):              items.append(build_item(p, p.GetDisplayText()))
350                  items.append(build_item(self.GetDefaultGroup(), _("'DEFAULT'")))  
351              elif isinstance(p, ClassGroupSingleton):  #           if isinstance(p, ClassGroupDefault):
352                  items.append(build_item(p, str(p.GetValue())))  #               items.append(build_item(self.GetDefaultGroup(), _("'DEFAULT'")))
353              elif isinstance(p, ClassGroupRange):  #           elif isinstance(p, ClassGroupSingleton):
354                  items.append(build_item(p, "%s - %s" %  #               items.append(build_item(p, str(p.GetValue())))
355                                             (p.GetMin(), p.GetMax())))  #           elif isinstance(p, ClassGroupRange):
356    #               items.append(build_item(p, "%s - %s" %
357    #                                          (p.GetMin(), p.GetMax())))
358    
359          return (_("Classification"), items)          return (_("Classification"), items)
360    
# Line 328  class ClassGroupProperties: Line 418  class ClassGroupProperties:
418    
419          props -- a ClassGroupProperties object. The class is copied if          props -- a ClassGroupProperties object. The class is copied if
420                   prop is not None. Otherwise, a default set of properties                   prop is not None. Otherwise, a default set of properties
421                   is created.                   is created such that: line color = Color.Black, line width = 1,
422                     and fill color = Color.Transparent
423          """          """
424    
425          self.stroke = None          #self.stroke = None
426          self.strokeWidth = 0          #self.strokeWidth = 0
427          self.fill = None          #self.fill = None
428    
429          if props is not None:          if props is not None:
430              self.SetProperties(props)              self.SetProperties(props)
431          else:          else:
432              self.SetLineColor(Color.None)              self.SetLineColor(Color.Black)
433              self.SetLineWidth(1)              self.SetLineWidth(1)
434              self.SetFill(Color.None)              self.SetFill(Color.Transparent)
435    
436      def SetProperties(self, props):      def SetProperties(self, props):
437          """Set this class's properties to those in class props."""          """Set this class's properties to those in class props."""
438    
439          assert(isinstance(props, ClassGroupProperties))          assert isinstance(props, ClassGroupProperties)
440          self.SetLineColor(props.GetLineColor())          self.SetLineColor(props.GetLineColor())
441          self.SetLineWidth(props.GetLineWidth())          self.SetLineWidth(props.GetLineWidth())
442          self.SetFill(props.GetFill())          self.SetFill(props.GetFill())
443                    
444      def GetLineColor(self):      def GetLineColor(self):
445          """Return the line color as a Color object."""          """Return the line color as a Color object."""
446          return self.stroke          return self.__stroke
447    
448      def SetLineColor(self, color):      def SetLineColor(self, color):
449          """Set the line color.          """Set the line color.
# Line 360  class ClassGroupProperties: Line 451  class ClassGroupProperties:
451          color -- the color of the line. This must be a Color object.          color -- the color of the line. This must be a Color object.
452          """          """
453    
454          assert(isinstance(color, Color))          self.__stroke = color
         self.stroke = color  
455    
456      def GetLineWidth(self):      def GetLineWidth(self):
457          """Return the line width."""          """Return the line width."""
458          return self.strokeWidth          return self.__strokeWidth
459    
460      def SetLineWidth(self, lineWidth):      def SetLineWidth(self, lineWidth):
461          """Set the line width.          """Set the line width.
462    
463          lineWidth -- the new line width. This must be > 0.          lineWidth -- the new line width. This must be > 0.
464          """          """
465          assert(isinstance(lineWidth, IntType))          assert isinstance(lineWidth, types.IntType)
466          if (lineWidth < 1):          if (lineWidth < 1):
467              raise ValueError(_("lineWidth < 1"))              raise ValueError(_("lineWidth < 1"))
468    
469          self.strokeWidth = lineWidth          self.__strokeWidth = lineWidth
470    
471      def GetFill(self):      def GetFill(self):
472          """Return the fill color as a Color object."""          """Return the fill color as a Color object."""
473          return self.fill          return self.__fill
474    
475      def SetFill(self, fill):      def SetFill(self, fill):
476          """Set the fill color.          """Set the fill color.
# Line 388  class ClassGroupProperties: Line 478  class ClassGroupProperties:
478          fill -- the color of the fill. This must be a Color object.          fill -- the color of the fill. This must be a Color object.
479          """          """
480    
481          assert(isinstance(fill, Color))          self.__fill = fill
         self.fill = fill  
482    
483        def __eq__(self, other):
484            """Return true if 'props' has the same attributes as this class"""
485    
486            #
487            # using 'is' over '==' results in a huge performance gain
488            # in the renderer
489            #
490            return isinstance(other, ClassGroupProperties)   \
491                and (self.__stroke is other.__stroke or      \
492                     self.__stroke == other.__stroke)        \
493                and (self.__fill is other.__fill or          \
494                     self.__fill == other.__fill)            \
495                and self.__strokeWidth == other.__strokeWidth
496    
497        def __ne__(self, other):
498            return not self.__eq__(other)
499    
500        def __copy__(self):
501            return ClassGroupProperties(self)
502    
503        def __deepcopy__(self):
504            return ClassGroupProperties(self)
505    
506        def __repr__(self):
507            return repr((self.__stroke, self.__strokeWidth, self.__fill))
508    
509  class ClassGroup:  class ClassGroup:
510      """A base class for all Groups within a Classification"""      """A base class for all Groups within a Classification"""
511    
512      def __init__(self, label = ""):      def __init__(self, label = "", props = None, group = None):
513          """Constructor.          """Constructor.
514    
515          label -- A string representing the Group's label          label -- A string representing the Group's label
516          """          """
517    
518          self.label = None          if group is not None:
519                self.SetLabel(copy.copy(group.GetLabel()))
520          self.SetLabel(label)              self.SetProperties(copy.copy(group.GetProperties()))
521                self.SetVisible(group.IsVisible())
522            else:
523                self.SetLabel(label)
524                self.SetProperties(props)
525                self.SetVisible(True)
526    
527      def GetLabel(self):      def GetLabel(self):
528          """Return the Group's label."""          """Return the Group's label."""
# Line 415  class ClassGroup: Line 534  class ClassGroup:
534          label -- a string representing the Group's label. This must          label -- a string representing the Group's label. This must
535                   not be None.                   not be None.
536          """          """
537          assert(isinstance(label, StringType))          assert isinstance(label, types.StringTypes)
538          self.label = label          self.label = label
539    
540        def GetDisplayText(self):
541            assert False, "GetDisplay must be overridden by subclass!"
542            return ""
543    
544      def Matches(self, value):      def Matches(self, value):
545          """Determines if this Group is associated with the given value.          """Determines if this Group is associated with the given value.
546    
547          Returns True or False. This needs to be implemented by all subclasses.          Returns False. This needs to be overridden by all subclasses.
548          """          """
549          pass          assert False, "GetMatches must be overridden by subclass!"
550            return False
551    
552      def GetProperties(self):      def GetProperties(self):
553          """Return the properties associated with the given value.          """Return the properties associated with the given value."""
554    
555          This needs to be implemented by all subclasses.          return self.prop
         """  
         pass  
556    
557        def SetProperties(self, prop):
558            """Set the properties associated with this Group.
559    
560            prop -- a ClassGroupProperties object. if prop is None,
561                    a default set of properties is created.
562            """
563    
564            if prop is None: prop = ClassGroupProperties()
565            assert isinstance(prop, ClassGroupProperties)
566            self.prop = prop
567    
568        def IsVisible(self):
569            return self.visible
570    
571        def SetVisible(self, visible):
572            self.visible = visible
573    
574        def __eq__(self, other):
575            return isinstance(other, ClassGroup) \
576                and self.label == other.label \
577                and self.GetProperties() == other.GetProperties()
578    
579        def __ne__(self, other):
580            return not self.__eq__(other)
581    
582        def __repr__(self):
583            return repr(self.label) + ", " + repr(self.GetProperties())
584            
585  class ClassGroupSingleton(ClassGroup):  class ClassGroupSingleton(ClassGroup):
586      """A Group that is associated with a single value."""      """A Group that is associated with a single value."""
587    
588      def __init__(self, value = 0, prop = None, label = ""):      def __init__(self, value = 0, props = None, label = "", group = None):
589          """Constructor.          """Constructor.
590    
591          value -- the associated value.          value -- the associated value.
# Line 446  class ClassGroupSingleton(ClassGroup): Line 595  class ClassGroupSingleton(ClassGroup):
595    
596          label -- a label for this group.          label -- a label for this group.
597          """          """
598          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label, props, group)
   
         self.prop = None  
         self.value = None  
599    
600          self.SetValue(value)          self.SetValue(value)
         self.SetProperties(prop)  
601    
602      def __copy__(self):      def __copy__(self):
603          return ClassGroupSingleton(self.value, self.prop, self.label)          return ClassGroupSingleton(self.GetValue(),
604                                       self.GetProperties(),
605                                       self.GetLabel())
606    
607        def __deepcopy__(self, memo):
608            return ClassGroupSingleton(self.GetValue(), group = self)
609    
610      def GetValue(self):      def GetValue(self):
611          """Return the associated value."""          """Return the associated value."""
612          return self.value          return self.__value
613    
614      def SetValue(self, value):      def SetValue(self, value):
615          """Associate this Group with the given value."""          """Associate this Group with the given value."""
616          self.value = value          self.__value = value
617    
618      def Matches(self, value):      def Matches(self, value):
619          """Determine if the given value matches the associated Group value."""          """Determine if the given value matches the associated Group value."""
620    
621          """Returns True if the value matches, False otherwise."""          """Returns True if the value matches, False otherwise."""
622    
623          return self.value == value          return self.__value == value
624    
625      def GetProperties(self):      def GetDisplayText(self):
626          """Return the Properties associated with this Group."""          label = self.GetLabel()
627    
628          return self.prop          if label != "": return label
629    
630      def SetProperties(self, prop):          return str(self.GetValue())
         """Set the properties associated with this Group.  
631    
632          prop -- a ClassGroupProperties object. if prop is None,      def __eq__(self, other):
633                  a default set of properties is created.          return ClassGroup.__eq__(self, other) \
634          """              and isinstance(other, ClassGroupSingleton) \
635                and self.__value == other.__value
636    
637          if prop is None: prop = ClassGroupProperties()      def __repr__(self):
638          assert(isinstance(prop, ClassGroupProperties))          return "(" + repr(self.__value) + ", " + ClassGroup.__repr__(self) + ")"
         self.prop = prop  
639    
640    class ClassGroupDefault(ClassGroup):
 class ClassGroupDefault(ClassGroupSingleton):  
641      """The default Group. When values do not match any other      """The default Group. When values do not match any other
642         Group within a Classification, the properties from this         Group within a Classification, the properties from this
643         class are used."""         class are used."""
644    
645      def __init__(self, prop = None, label = ""):      def __init__(self, props = None, label = "", group = None):
646          """Constructor.          """Constructor.
647    
648          prop -- a ClassGroupProperites object. If prop is None a default          prop -- a ClassGroupProperites object. If prop is None a default
# Line 503  class ClassGroupDefault(ClassGroupSingle Line 651  class ClassGroupDefault(ClassGroupSingle
651          label -- a label for this group.          label -- a label for this group.
652          """          """
653    
654          ClassGroupSingleton.__init__(self, 0, prop, label)          ClassGroup.__init__(self, label, props, group)
655    
656      def __copy__(self):      def __copy__(self):
657          return ClassGroupDefault(self.prop, self.label)          return ClassGroupDefault(self.GetProperties(), self.GetLabel())
658    
659      def GetProperties(self):      def __deepcopy__(self, memo):
660          """Return the Properties associated with this Group."""          return ClassGroupDefault(label = self.GetLabel(), group = self)
661          return self.prop  
662        def Matches(self, value):
663            return True
664    
665        def GetDisplayText(self):
666            label = self.GetLabel()
667    
668            if label != "": return label
669    
670            return _("DEFAULT")
671    
672        def __eq__(self, other):
673            return ClassGroup.__eq__(self, other) \
674                and isinstance(other, ClassGroupDefault) \
675                and self.GetProperties() == other.GetProperties()
676    
677        def __repr__(self):
678            return "(" + ClassGroup.__repr__(self) + ")"
679    
680  class ClassGroupRange(ClassGroup):  class ClassGroupRange(ClassGroup):
681      """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
682         set of properties."""         set of properties."""
683    
684      def __init__(self, min = 0, max = 1, prop = None, label = ""):      def __init__(self, min = 0, max = 1, props = None, label = "", group=None):
685          """Constructor.          """Constructor.
686    
687          The minumum value must be strictly less than the maximum.          The minumum value must be strictly less than the maximum.
# Line 531  class ClassGroupRange(ClassGroup): Line 696  class ClassGroupRange(ClassGroup):
696          label -- a label for this group.          label -- a label for this group.
697          """          """
698    
699          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label, props, group)
   
         self.min = self.max = 0  
         self.prop = None  
700    
701            #self.__min = self.__max = 0
702            #self.__range = Range("[" + repr(float(min)) + ";" +
703                                       #repr(float(max)) + "[")
704          self.SetRange(min, max)          self.SetRange(min, max)
         self.SetProperties(prop)  
705    
706      def __copy__(self):      def __copy__(self):
707          return ClassGroupRange(self.min, self.max, self.prop, self.label)          return ClassGroupRange(min = self.__range,
708                                   max = None,
709                                   props = self.GetProperties(),
710                                   label = self.GetLabel())
711    
712        def __deepcopy__(self, memo):
713            return ClassGroupRange(min = copy.copy(self.__range),
714                                   max = copy.copy(self.GetMax()),
715                                   group = self)
716    
717      def GetMin(self):      def GetMin(self):
718          """Return the range's minimum value."""          """Return the range's minimum value."""
719          return self.min          return self.__range.GetRange()[1]
720    
721      def SetMin(self, min):      def SetMin(self, min):
722          """Set the range's minimum value.          """Set the range's minimum value.
# Line 553  class ClassGroupRange(ClassGroup): Line 725  class ClassGroupRange(ClassGroup):
725                 maximum value. Use SetRange() to change both min and max values.                 maximum value. Use SetRange() to change both min and max values.
726          """          """
727            
728          self.SetRange(min, self.max)          self.SetRange(min, self.__range.GetRange()[2])
729    
730      def GetMax(self):      def GetMax(self):
731          """Return the range's maximum value."""          """Return the range's maximum value."""
732          return self.max          return self.__range.GetRange()[2]
733    
734      def SetMax(self, max):      def SetMax(self, max):
735          """Set the range's maximum value.          """Set the range's maximum value.
# Line 565  class ClassGroupRange(ClassGroup): Line 737  class ClassGroupRange(ClassGroup):
737          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
738                 minimum value. Use SetRange() to change both min and max values.                 minimum value. Use SetRange() to change both min and max values.
739          """          """
740          self.SetRange(self.min, max)          self.SetRange(self.__range.GetRange()[1], max)
741    
742      def SetRange(self, min, max):      def SetRange(self, min, max = None):
743          """Set a new range.          """Set a new range.
744    
745          Note that min must be strictly less than max.          Note that min must be strictly less than max.
# Line 576  class ClassGroupRange(ClassGroup): Line 748  class ClassGroupRange(ClassGroup):
748          min -- the new maximum value          min -- the new maximum value
749          """          """
750    
751          if min >= max:          if isinstance(min, Range):
752              raise ValueError(_("ClassGroupRange: %i(min) >= %i(max)!") %              self.__range = min
753                               (min, max))          else:
754          self.min = min              if max is None:
755          self.max = max                  raise ValueError()
756    
757                self.__range = Range(("[", min, max, "["))
758    
759      def GetRange(self):      def GetRange(self):
760          """Return the range as a tuple (min, max)"""          """Return the range as a string"""
761          return (self.min, self.max)          #return (self.__min, self.__max)
762            return self.__range.string(self.__range.GetRange())
763    
764      def Matches(self, value):      def Matches(self, value):
765          """Determine if the given value lies with the current range.          """Determine if the given value lies with the current range.
# Line 592  class ClassGroupRange(ClassGroup): Line 767  class ClassGroupRange(ClassGroup):
767          The following check is used: min <= value < max.          The following check is used: min <= value < max.
768          """          """
769    
770          return self.min <= value < self.max          return operator.contains(self.__range, value)
771            #return self.__min <= value < self.__max
772    
773      def GetProperties(self):      def GetDisplayText(self):
774          """Return the Properties associated with this Group."""          label = self.GetLabel()
         return self.prop  
775    
776      def SetProperties(self, prop):          if label != "": return label
         """Set the properties associated with this Group.  
777    
778          prop -- a ClassGroupProperties object. if prop is None,          #return _("%s - %s") % (self.GetMin(), self.GetMax())
779                  a default set of properties is created.          #return repr(self.__range)
780          """          return self.__range.string(self.__range.GetRange())
781          if prop is None: prop = ClassGroupProperties()  
782          assert(isinstance(prop, ClassGroupProperties))      def __eq__(self, other):
783          self.prop = prop          return ClassGroup.__eq__(self, other) \
784                and isinstance(other, ClassGroupRange) \
785                and self.__range == other.__range
786                #and self.__min == other.__min \
787                #and self.__max == other.__max
788    
789        def __repr__(self):
790            return "(" + str(self.__range) + ClassGroup.__repr__(self) + ")"
791            #return "(" + repr(self.__min) + ", " + repr(self.__max) + ", " + \
792                   #ClassGroup.__repr__(self) + ")"
793    
794  class ClassGroupMap(ClassGroup):  class ClassGroupMap(ClassGroup):
795      """Currently, this class is not used."""      """Currently, this class is not used."""
# Line 631  class ClassGroupMap(ClassGroup): Line 814  class ClassGroupMap(ClassGroup):
814      def GetPropertiesFromValue(self, value):      def GetPropertiesFromValue(self, value):
815          pass          pass
816    
817        def GetDisplayText(self):
818            return "Map: " + self.map_type
819    
820      #      #
821      # built-in mappings      # built-in mappings
822      #      #

Legend:
Removed from v.462  
changed lines
  Added in v.1249

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26