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

Legend:
Removed from v.491  
changed lines
  Added in v.1351

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26