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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26