/[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 484 by jonathan, Fri Mar 7 18:20:10 2003 UTC revision 1176 by jonathan, Thu Jun 12 15:46:22 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  import copy  import copy, operator
27    
28  from types import *  from Thuban import _
29    
30  from messages import LAYER_PROJECTION_CHANGED, LAYER_LEGEND_CHANGED, \  import types
31       LAYER_VISIBILITY_CHANGED  
32    from messages import \
33        LAYER_PROJECTION_CHANGED, \
34        LAYER_LEGEND_CHANGED, \
35        LAYER_VISIBILITY_CHANGED
36    
 from Thuban import _  
37  from Thuban.Model.color import Color  from Thuban.Model.color import Color
38    from Thuban.Model.range import Range
39    
40  import Thuban.Model.layer  import Thuban.Model.layer
41    
 # constants  
 RANGE_MIN  = 0  
 RANGE_MAX  = 1  
 RANGE_DATA = 2  
   
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 __ToggleMessages(self, on):      def __deepcopy__(self, memo):
75          self.__sendMessages = on          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            for i in range(1, len(self.__groups)):
83                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             If there is no layer then the field type is set to None,          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          otherwise the layer is queried to find the type of the
97             field data          field data
98    
99             field -- if None then all values map to the default data          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                    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          self.SetFieldType(fieldType)          self.field = field
   
         # XXX: if fieldType comes back None then field isn't in the table!  
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 114  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      def SetLayer(self, layer):          A ValueError is raised if the owning layer is not None and
139          """Set the owning Layer of this classification."""          'type' is different from the current field type.
140            """
141    
142          if __debug__:          if type != self.fieldType:
143              if layer is not None:              if self.layer is not None:
144                  assert(isinstance(layer, Thuban.Model.layer.Layer))                  raise ValueError()
145                else:
146                    self.fieldType = type
147                    self.__SendNotification()
148    
149        def SetLayer(self, layer):
150            """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          # prevent infinite recursion when calling SetClassification()          # prevent infinite recursion when calling SetClassification()
157          if self.layer is not None and layer == self.layer:          if self.__setLayerLock: return
             return  
158    
159          self.layer = layer          self.__setLayerLock = True
         self.SetField(self.GetField()) # XXX: this sync's the fieldType  
160    
161          if self.layer is not None:          if layer is None:
162              self.layer.SetClassification(self)              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          #self.__SendMessage(LAYER_LEGEND_CHANGED)              old_layer = self.layer
170    
171      def GetLayer(self):              self.layer = layer
         """Return the parent layer."""  
         return self.layer  
172    
173      def SetDefaultGroup(self, group):              try:
174          """Set the group to be used when a value can't be classified.                  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             group -- group that the value maps to.          self.__setLayerLock = False
         """  
183    
184          assert(isinstance(group, ClassGroupDefault))      def GetLayer(self):
185          self.AddGroup(group)          """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 163  class Classification: Line 197  class Classification:
197    
198          fill -- a Color object.          fill -- a Color object.
199          """          """
         assert(isinstance(fill, Color))  
200          self.GetDefaultGroup().GetProperties().SetFill(fill)          self.GetDefaultGroup().GetProperties().SetFill(fill)
201          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendNotification()
202                    
203      def GetDefaultFill(self):      def GetDefaultFill(self):
204          """Return the default fill color."""          """Return the default fill color."""
# Line 176  class Classification: Line 209  class Classification:
209    
210          color -- a Color object.          color -- a Color object.
211          """          """
         assert(isinstance(color, Color))  
212          self.GetDefaultGroup().GetProperties().SetLineColor(color)          self.GetDefaultGroup().GetProperties().SetLineColor(color)
213          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendNotification()
214                    
215      def GetDefaultLineColor(self):      def GetDefaultLineColor(self):
216          """Return the default line color."""          """Return the default line color."""
# Line 189  class Classification: Line 221  class Classification:
221    
222          lineWidth -- an integer > 0.          lineWidth -- an integer > 0.
223          """          """
224          assert(isinstance(lineWidth, IntType))          assert isinstance(lineWidth, types.IntType)
225          self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)          self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)
226          self.__SendMessage(LAYER_LEGEND_CHANGED)          self.__SendNotification()
227                    
228      def GetDefaultLineWidth(self):      def GetDefaultLineWidth(self):
229          """Return the default line width."""          """Return the default line width."""
230          return self.GetDefaultGroup().GetProperties().GetLineWidth()          return self.GetDefaultGroup().GetProperties().GetLineWidth()
231                    
232      def AddGroup(self, item):  
233          """Add a new ClassGroup item to the classification.      #
234        # The methods that manipulate self.__groups have to be kept in
235        # sync. We store the default group in index 0 to make it
236        # convienent to iterate over the classification's groups, but
237        # from the user's perspective the first (non-default) group is
238        # at index 0 and the DefaultGroup is a special entity.
239        #
240    
241        def SetDefaultGroup(self, group):
242            """Set the group to be used when a value can't be classified.
243    
244            group -- group that the value maps to.
245            """
246    
247            assert isinstance(group, ClassGroupDefault)
248            if len(self.__groups) > 0:
249                self.__groups[0] = group
250            else:
251                self.__groups.append(group)
252    
253        def GetDefaultGroup(self):
254            """Return the default group."""
255            return self.__groups[0]
256    
257        def AppendGroup(self, item):
258            """Append a new ClassGroup item to the classification.
259    
260          item -- this must be a valid ClassGroup object          item -- this must be a valid ClassGroup object
261          """          """
262    
263          assert(isinstance(item, ClassGroup))          self.InsertGroup(self.GetNumGroups(), item)
264    
265          if len(self.groups) > 0 and isinstance(item, ClassGroupDefault):      def InsertGroup(self, index, group):
266              self.groups[0] = item          
267              #self.SetDefaultGroup(item)          assert isinstance(group, ClassGroup)
268          else:  
269              self.groups.append(item)          self.__groups.insert(index + 1, group)
270    
271            self.__SendNotification()
272    
273        def RemoveGroup(self, index):
274            return self.__groups.pop(index + 1)
275    
276        def ReplaceGroup(self, index, group):
277            assert isinstance(group, ClassGroup)
278    
279            self.__groups[index + 1] = group
280    
281            self.__SendNotification()
282    
283        def GetGroup(self, index):
284            return self.__groups[index + 1]
285    
286        def GetNumGroups(self):
287            """Return the number of non-default groups in the classification."""
288            return len(self.__groups) - 1
289    
         self.__SendMessage(LAYER_LEGEND_CHANGED)  
290    
291      def GetGroup(self, value):      def FindGroup(self, value):
292          """Return the associated group, or the default group.          """Return the associated group, or the default group.
293    
294             Groups are checked in the order the were added to the          Groups are checked in the order the were added to the
295             Classification.          Classification.
296    
297             value -- the value to classify. If there is no mapping,          value -- the value to classify. If there is no mapping,
298                      the field is None or value is None,                   the field is None or value is None,
299                      return the default properties                   return the default properties
300          """          """
301    
302          if self.GetField() is not None and value is not None:          if self.GetField() is not None and value is not None:
303    
304              for i in range(1, len(self.groups)):              for i in range(1, len(self.__groups)):
305                  group = self.groups[i]                  group = self.__groups[i]
306                  if group.Matches(value):                  if group.Matches(value):
307                      return group                      return group
308    
309          return self.GetDefaultGroup()          return self.GetDefaultGroup()
310    
311      def GetProperties(self, value):      def GetProperties(self, value):
312          """Return the properties associated with the given value."""          """Return the properties associated with the given value.
313          
314            Use this function rather than Classification.FindGroup().GetProperties()
315            since the returned group may be a ClassGroupMap which doesn't support
316            a call to GetProperties().
317            """
318    
319          group = self.GetGroup(value)          group = self.FindGroup(value)
320          if isinstance(group, ClassGroupMap):          if isinstance(group, ClassGroupMap):
321              return group.GetPropertiesFromValue(value)              return group.GetPropertiesFromValue(value)
322          else:          else:
# Line 246  class Classification: Line 326  class Classification:
326          items = []          items = []
327    
328          def build_color_item(text, color):          def build_color_item(text, color):
329              if color is Color.None:              if color is Color.Transparent:
330                  return ("%s: %s" % (text, _("None")), None)                  return ("%s: %s" % (text, _("None")), None)
331    
332              return ("%s: (%.3f, %.3f, %.3f)" %              return ("%s: (%.3f, %.3f, %.3f)" %
# Line 271  class Classification: Line 351  class Classification:
351              return (label, i)              return (label, i)
352    
353          for p in self:          for p in self:
354              if isinstance(p, ClassGroupDefault):              items.append(build_item(p, p.GetDisplayText()))
355                  items.append(build_item(self.GetDefaultGroup(), _("'DEFAULT'")))  
356              elif isinstance(p, ClassGroupSingleton):  #           if isinstance(p, ClassGroupDefault):
357                  items.append(build_item(p, str(p.GetValue())))  #               items.append(build_item(self.GetDefaultGroup(), _("'DEFAULT'")))
358              elif isinstance(p, ClassGroupRange):  #           elif isinstance(p, ClassGroupSingleton):
359                  items.append(build_item(p, "%s - %s" %  #               items.append(build_item(p, str(p.GetValue())))
360                                             (p.GetMin(), p.GetMax())))  #           elif isinstance(p, ClassGroupRange):
361    #               items.append(build_item(p, "%s - %s" %
362    #                                          (p.GetMin(), p.GetMax())))
363    
364          return (_("Classification"), items)          return (_("Classification"), items)
365    
# Line 342  class ClassGroupProperties: Line 424  class ClassGroupProperties:
424          props -- a ClassGroupProperties object. The class is copied if          props -- a ClassGroupProperties object. The class is copied if
425                   prop is not None. Otherwise, a default set of properties                   prop is not None. Otherwise, a default set of properties
426                   is created such that: line color = Color.Black, line width = 1,                   is created such that: line color = Color.Black, line width = 1,
427                   and fill color = Color.None                   and fill color = Color.Transparent
428          """          """
429    
430          self.stroke = None          #self.stroke = None
431          self.strokeWidth = 0          #self.strokeWidth = 0
432          self.fill = None          #self.fill = None
433    
434          if props is not None:          if props is not None:
435              self.SetProperties(props)              self.SetProperties(props)
436          else:          else:
437              self.SetLineColor(Color.Black)              self.SetLineColor(Color.Black)
438              self.SetLineWidth(1)              self.SetLineWidth(1)
439              self.SetFill(Color.None)              self.SetFill(Color.Transparent)
440    
441      def SetProperties(self, props):      def SetProperties(self, props):
442          """Set this class's properties to those in class props."""          """Set this class's properties to those in class props."""
443    
444          assert(isinstance(props, ClassGroupProperties))          assert isinstance(props, ClassGroupProperties)
445          self.SetLineColor(props.GetLineColor())          self.SetLineColor(props.GetLineColor())
446          self.SetLineWidth(props.GetLineWidth())          self.SetLineWidth(props.GetLineWidth())
447          self.SetFill(props.GetFill())          self.SetFill(props.GetFill())
448                    
449      def GetLineColor(self):      def GetLineColor(self):
450          """Return the line color as a Color object."""          """Return the line color as a Color object."""
451          return self.stroke          return self.__stroke
452    
453      def SetLineColor(self, color):      def SetLineColor(self, color):
454          """Set the line color.          """Set the line color.
# Line 374  class ClassGroupProperties: Line 456  class ClassGroupProperties:
456          color -- the color of the line. This must be a Color object.          color -- the color of the line. This must be a Color object.
457          """          """
458    
459          assert(isinstance(color, Color))          self.__stroke = color
         self.stroke = color  
460    
461      def GetLineWidth(self):      def GetLineWidth(self):
462          """Return the line width."""          """Return the line width."""
463          return self.strokeWidth          return self.__strokeWidth
464    
465      def SetLineWidth(self, lineWidth):      def SetLineWidth(self, lineWidth):
466          """Set the line width.          """Set the line width.
467    
468          lineWidth -- the new line width. This must be > 0.          lineWidth -- the new line width. This must be > 0.
469          """          """
470          assert(isinstance(lineWidth, IntType))          assert isinstance(lineWidth, types.IntType)
471          if (lineWidth < 1):          if (lineWidth < 1):
472              raise ValueError(_("lineWidth < 1"))              raise ValueError(_("lineWidth < 1"))
473    
474          self.strokeWidth = lineWidth          self.__strokeWidth = lineWidth
475    
476      def GetFill(self):      def GetFill(self):
477          """Return the fill color as a Color object."""          """Return the fill color as a Color object."""
478          return self.fill          return self.__fill
479    
480      def SetFill(self, fill):      def SetFill(self, fill):
481          """Set the fill color.          """Set the fill color.
# Line 402  class ClassGroupProperties: Line 483  class ClassGroupProperties:
483          fill -- the color of the fill. This must be a Color object.          fill -- the color of the fill. This must be a Color object.
484          """          """
485    
486          assert(isinstance(fill, Color))          self.__fill = fill
         self.fill = fill  
487    
488      def __eq__(self, other):      def __eq__(self, other):
489          """Return true if 'props' has the same attributes as this class"""          """Return true if 'props' has the same attributes as this class"""
490    
491            #
492            # using 'is' over '==' results in a huge performance gain
493            # in the renderer
494            #
495          return isinstance(other, ClassGroupProperties)   \          return isinstance(other, ClassGroupProperties)   \
496              and self.stroke      == other.GetLineColor() \              and (self.__stroke is other.__stroke or      \
497              and self.strokeWidth == other.GetLineWidth() \                   self.__stroke == other.__stroke)        \
498              and self.fill        == other.GetFill()              and (self.__fill is other.__fill or          \
499                     self.__fill == other.__fill)            \
500                and self.__strokeWidth == other.__strokeWidth
501    
502      def __ne__(self, other):      def __ne__(self, other):
503          return not self.__eq__(other)          return not self.__eq__(other)
# Line 419  class ClassGroupProperties: Line 505  class ClassGroupProperties:
505      def __copy__(self):      def __copy__(self):
506          return ClassGroupProperties(self)          return ClassGroupProperties(self)
507    
508        def __deepcopy__(self):
509            return ClassGroupProperties(self)
510    
511        def __repr__(self):
512            return repr((self.__stroke, self.__strokeWidth, self.__fill))
513    
514  class ClassGroup:  class ClassGroup:
515      """A base class for all Groups within a Classification"""      """A base class for all Groups within a Classification"""
516    
517      def __init__(self, label = ""):      def __init__(self, label = "", props = None, group = None):
518          """Constructor.          """Constructor.
519    
520          label -- A string representing the Group's label          label -- A string representing the Group's label
521          """          """
522    
523          self.label = None          if group is not None:
524                self.SetLabel(copy.copy(group.GetLabel()))
525          self.SetLabel(label)              self.SetProperties(copy.copy(group.GetProperties()))
526                self.SetVisible(group.IsVisible())
527            else:
528                self.SetLabel(label)
529                self.SetProperties(props)
530                self.SetVisible(True)
531    
532      def GetLabel(self):      def GetLabel(self):
533          """Return the Group's label."""          """Return the Group's label."""
# Line 442  class ClassGroup: Line 539  class ClassGroup:
539          label -- a string representing the Group's label. This must          label -- a string representing the Group's label. This must
540                   not be None.                   not be None.
541          """          """
542          assert(isinstance(label, StringType))          assert isinstance(label, types.StringTypes)
543          self.label = label          self.label = label
544    
545        def GetDisplayText(self):
546            assert False, "GetDisplay must be overridden by subclass!"
547            return ""
548    
549      def Matches(self, value):      def Matches(self, value):
550          """Determines if this Group is associated with the given value.          """Determines if this Group is associated with the given value.
551    
552          Returns False. This needs to be overridden by all subclasses.          Returns False. This needs to be overridden by all subclasses.
553          """          """
554            assert False, "GetMatches must be overridden by subclass!"
555          return False          return False
556    
557      def GetProperties(self):      def GetProperties(self):
558          """Return the properties associated with the given value.          """Return the properties associated with the given value."""
559    
560          Returns None. This needs to be overridden by all subclasses.          return self.prop
         """  
         return None  
561    
562        def SetProperties(self, prop):
563            """Set the properties associated with this Group.
564    
565            prop -- a ClassGroupProperties object. if prop is None,
566                    a default set of properties is created.
567            """
568    
569            if prop is None: prop = ClassGroupProperties()
570            assert isinstance(prop, ClassGroupProperties)
571            self.prop = prop
572    
573        def IsVisible(self):
574            return self.visible
575    
576        def SetVisible(self, visible):
577            self.visible = visible
578    
579        def __eq__(self, other):
580            return isinstance(other, ClassGroup) \
581                and self.label == other.label \
582                and self.GetProperties() == other.GetProperties()
583    
584        def __ne__(self, other):
585            return not self.__eq__(other)
586    
587        def __repr__(self):
588            return repr(self.label) + ", " + repr(self.GetProperties())
589            
590  class ClassGroupSingleton(ClassGroup):  class ClassGroupSingleton(ClassGroup):
591      """A Group that is associated with a single value."""      """A Group that is associated with a single value."""
592    
593      def __init__(self, value = 0, prop = None, label = ""):      def __init__(self, value = 0, props = None, label = "", group = None):
594          """Constructor.          """Constructor.
595    
596          value -- the associated value.          value -- the associated value.
# Line 473  class ClassGroupSingleton(ClassGroup): Line 600  class ClassGroupSingleton(ClassGroup):
600    
601          label -- a label for this group.          label -- a label for this group.
602          """          """
603          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label, props, group)
   
         self.prop = None  
         self.value = None  
604    
605          self.SetValue(value)          self.SetValue(value)
         self.SetProperties(prop)  
606    
607      def __copy__(self):      def __copy__(self):
608          return ClassGroupSingleton(self.GetValue(),          return ClassGroupSingleton(self.GetValue(),
# Line 487  class ClassGroupSingleton(ClassGroup): Line 610  class ClassGroupSingleton(ClassGroup):
610                                     self.GetLabel())                                     self.GetLabel())
611    
612      def __deepcopy__(self, memo):      def __deepcopy__(self, memo):
613          return ClassGroupSingleton(copy.copy(self.GetValue()),          return ClassGroupSingleton(self.GetValue(), group = self)
                                    copy.copy(self.GetProperties()),  
                                    copy.copy(self.GetLabel()))  
614    
615      def GetValue(self):      def GetValue(self):
616          """Return the associated value."""          """Return the associated value."""
617          return self.value          return self.__value
618    
619      def SetValue(self, value):      def SetValue(self, value):
620          """Associate this Group with the given value."""          """Associate this Group with the given value."""
621          self.value = value          self.__value = value
622    
623      def Matches(self, value):      def Matches(self, value):
624          """Determine if the given value matches the associated Group value."""          """Determine if the given value matches the associated Group value."""
625    
626          """Returns True if the value matches, False otherwise."""          """Returns True if the value matches, False otherwise."""
627    
628          return self.value == value          return self.__value == value
629    
630      def GetProperties(self):      def GetDisplayText(self):
631          """Return the Properties associated with this Group."""          label = self.GetLabel()
632    
633          return self.prop          if label != "": return label
634    
635      def SetProperties(self, prop):          return str(self.GetValue())
         """Set the properties associated with this Group.  
   
         prop -- a ClassGroupProperties object. if prop is None,  
                 a default set of properties is created.  
         """  
   
         if prop is None: prop = ClassGroupProperties()  
         assert(isinstance(prop, ClassGroupProperties))  
         self.prop = prop  
636    
637      def __eq__(self, other):      def __eq__(self, other):
638          return isinstance(other, ClassGroupSingleton) \          return ClassGroup.__eq__(self, other) \
639              and self.GetProperties() == other.GetProperties() \              and isinstance(other, ClassGroupSingleton) \
640              and self.GetValue() == other.GetValue()              and self.__value == other.__value
641    
642      def __ne__(self, other):      def __repr__(self):
643          return not self.__eq__(other)          return "(" + repr(self.__value) + ", " + ClassGroup.__repr__(self) + ")"
644    
645  class ClassGroupDefault(ClassGroup):  class ClassGroupDefault(ClassGroup):
646      """The default Group. When values do not match any other      """The default Group. When values do not match any other
647         Group within a Classification, the properties from this         Group within a Classification, the properties from this
648         class are used."""         class are used."""
649    
650      def __init__(self, prop = None, label = ""):      def __init__(self, props = None, label = "", group = None):
651          """Constructor.          """Constructor.
652    
653          prop -- a ClassGroupProperites object. If prop is None a default          prop -- a ClassGroupProperites object. If prop is None a default
# Line 544  class ClassGroupDefault(ClassGroup): Line 656  class ClassGroupDefault(ClassGroup):
656          label -- a label for this group.          label -- a label for this group.
657          """          """
658    
659          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label, props, group)
         self.SetProperties(prop)  
660    
661      def __copy__(self):      def __copy__(self):
662          return ClassGroupDefault(self.GetProperties(), self.GetLabel())          return ClassGroupDefault(self.GetProperties(), self.GetLabel())
663    
664      def __deepcopy__(self, memo):      def __deepcopy__(self, memo):
665          return ClassGroupDefault(copy.copy(self.GetProperties()),          return ClassGroupDefault(label = self.GetLabel(), group = self)
                                  copy.copy(self.GetLabel()))  
666    
667      def Matches(self, value):      def Matches(self, value):
668          return True          return True
669    
670      def GetProperties(self):      def GetDisplayText(self):
671          """Return the Properties associated with this Group."""          label = self.GetLabel()
         return self.prop  
   
     def SetProperties(self, prop):  
         """Set the properties associated with this Group.  
672    
673          prop -- a ClassGroupProperties object. if prop is None,          if label != "": return label
                 a default set of properties is created.  
         """  
674    
675          if prop is None: prop = ClassGroupProperties()          return _("DEFAULT")
         assert(isinstance(prop, ClassGroupProperties))  
         self.prop = prop  
676    
677      def __eq__(self, other):      def __eq__(self, other):
678          return isinstance(other, ClassGroupDefault) \          return ClassGroup.__eq__(self, other) \
679                and isinstance(other, ClassGroupDefault) \
680              and self.GetProperties() == other.GetProperties()              and self.GetProperties() == other.GetProperties()
681    
682      def __ne__(self, other):      def __repr__(self):
683          return not self.__eq__(other)          return "(" + ClassGroup.__repr__(self) + ")"
684    
685  class ClassGroupRange(ClassGroup):  class ClassGroupRange(ClassGroup):
686      """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
687         set of properties."""         set of properties."""
688    
689      def __init__(self, min = 0, max = 1, prop = None, label = ""):      def __init__(self, min = 0, max = 1, props = None, label = "", group=None):
690          """Constructor.          """Constructor.
691    
692          The minumum value must be strictly less than the maximum.          The minumum value must be strictly less than the maximum.
# Line 598  class ClassGroupRange(ClassGroup): Line 701  class ClassGroupRange(ClassGroup):
701          label -- a label for this group.          label -- a label for this group.
702          """          """
703    
704          ClassGroup.__init__(self, label)          ClassGroup.__init__(self, label, props, group)
   
         self.min = self.max = 0  
         self.prop = None  
705    
706            #self.__min = self.__max = 0
707            #self.__range = Range("[" + repr(float(min)) + ";" +
708                                       #repr(float(max)) + "[")
709          self.SetRange(min, max)          self.SetRange(min, max)
         self.SetProperties(prop)  
710    
711      def __copy__(self):      def __copy__(self):
712          return ClassGroupRange(self.GetMin(),          return ClassGroupRange(min = self.__range,
713                                 self.GetMax(),                                 max = None,
714                                 self.GetProperties(),                                 props = self.GetProperties(),
715                                 self.GetLabel())                                 label = self.GetLabel())
716    
717      def __deepcopy__(self, memo):      def __deepcopy__(self, memo):
718          return ClassGroupRange(copy.copy(self.GetMin()),          return ClassGroupRange(min = copy.copy(self.__range),
719                                 copy.copy(self.GetMax()),                                 max = copy.copy(self.GetMax()),
720                                 copy.copy(self.GetProperties()),                                 group = self)
                                copy.copy(self.GetLabel()))  
721    
722      def GetMin(self):      def GetMin(self):
723          """Return the range's minimum value."""          """Return the range's minimum value."""
724          return self.min          return self.__range.GetRange()[1]
725    
726      def SetMin(self, min):      def SetMin(self, min):
727          """Set the range's minimum value.          """Set the range's minimum value.
# Line 629  class ClassGroupRange(ClassGroup): Line 730  class ClassGroupRange(ClassGroup):
730                 maximum value. Use SetRange() to change both min and max values.                 maximum value. Use SetRange() to change both min and max values.
731          """          """
732            
733          self.SetRange(min, self.max)          self.SetRange(min, self.__range.GetRange()[2])
734    
735      def GetMax(self):      def GetMax(self):
736          """Return the range's maximum value."""          """Return the range's maximum value."""
737          return self.max          return self.__range.GetRange()[2]
738    
739      def SetMax(self, max):      def SetMax(self, max):
740          """Set the range's maximum value.          """Set the range's maximum value.
# Line 641  class ClassGroupRange(ClassGroup): Line 742  class ClassGroupRange(ClassGroup):
742          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
743                 minimum value. Use SetRange() to change both min and max values.                 minimum value. Use SetRange() to change both min and max values.
744          """          """
745          self.SetRange(self.min, max)          self.SetRange(self.__range.GetRange()[1], max)
746    
747      def SetRange(self, min, max):      def SetRange(self, min, max = None):
748          """Set a new range.          """Set a new range.
749    
750          Note that min must be strictly less than max.          Note that min must be strictly less than max.
# Line 652  class ClassGroupRange(ClassGroup): Line 753  class ClassGroupRange(ClassGroup):
753          min -- the new maximum value          min -- the new maximum value
754          """          """
755    
756          if min >= max:          if isinstance(min, Range):
757              raise ValueError(_("ClassGroupRange: %i(min) >= %i(max)!") %              self.__range = min
758                               (min, max))          else:
759          self.min = min              if max is None:
760          self.max = max                  raise ValueError()
761    
762                self.__range = Range(("[", min, max, "["))
763    
764      def GetRange(self):      def GetRange(self):
765          """Return the range as a tuple (min, max)"""          """Return the range as a string"""
766          return (self.min, self.max)          #return (self.__min, self.__max)
767            return self.__range.string(self.__range.GetRange())
768    
769      def Matches(self, value):      def Matches(self, value):
770          """Determine if the given value lies with the current range.          """Determine if the given value lies with the current range.
# Line 668  class ClassGroupRange(ClassGroup): Line 772  class ClassGroupRange(ClassGroup):
772          The following check is used: min <= value < max.          The following check is used: min <= value < max.
773          """          """
774    
775          return self.min <= value < self.max          return operator.contains(self.__range, value)
776            #return self.__min <= value < self.__max
777    
778      def GetProperties(self):      def GetDisplayText(self):
779          """Return the Properties associated with this Group."""          label = self.GetLabel()
         return self.prop  
780    
781      def SetProperties(self, prop):          if label != "": return label
         """Set the properties associated with this Group.  
782    
783          prop -- a ClassGroupProperties object. if prop is None,          #return _("%s - %s") % (self.GetMin(), self.GetMax())
784                  a default set of properties is created.          #return repr(self.__range)
785          """          return self.__range.string(self.__range.GetRange())
         if prop is None: prop = ClassGroupProperties()  
         assert(isinstance(prop, ClassGroupProperties))  
         self.prop = prop  
786    
787      def __eq__(self, other):      def __eq__(self, other):
788          return isinstance(other, ClassGroupRange) \          return ClassGroup.__eq__(self, other) \
789              and self.GetProperties() == other.GetProperties() \              and isinstance(other, ClassGroupRange) \
790              and self.GetRange() == other.GetRange()              and self.__range == other.__range
791                #and self.__min == other.__min \
792      def __ne__(self, other):              #and self.__max == other.__max
793          return not self.__eq__(other)  
794        def __repr__(self):
795            return "(" + str(self.__range) + ClassGroup.__repr__(self) + ")"
796            #return "(" + repr(self.__min) + ", " + repr(self.__max) + ", " + \
797                   #ClassGroup.__repr__(self) + ")"
798    
799  class ClassGroupMap(ClassGroup):  class ClassGroupMap(ClassGroup):
800      """Currently, this class is not used."""      """Currently, this class is not used."""
# Line 715  class ClassGroupMap(ClassGroup): Line 819  class ClassGroupMap(ClassGroup):
819      def GetPropertiesFromValue(self, value):      def GetPropertiesFromValue(self, value):
820          pass          pass
821    
822        def GetDisplayText(self):
823            return "Map: " + self.map_type
824    
825      #      #
826      # built-in mappings      # built-in mappings
827      #      #

Legend:
Removed from v.484  
changed lines
  Added in v.1176

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26