/[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

trunk/thuban/Thuban/Model/classification.py revision 960 by jonathan, Wed May 21 17:23:11 2003 UTC branches/WIP-pyshapelib-bramz/Thuban/Model/classification.py revision 2734 by bramz, Thu Mar 1 12:42:59 2007 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001, 2003 by Intevation GmbH  # Copyright (c) 2001, 2003, 2005, 2006 by Intevation GmbH
2  # Authors:  # Authors:
3  # Jonathan Coles <[email protected]>  # Jonathan Coles <[email protected]>
4    # Jan-Oliver Wagner <[email protected]> (2005)
5    # Frank Koormann <[email protected]> (2006)
6  #  #
7  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
8  # Read the file COPYING coming with Thuban for details.  # Read the file COPYING coming with Thuban for details.
# Line 20  See the description of FindGroup() for m Line 22  See the description of FindGroup() for m
22  on the mapping algorithm.  on the mapping algorithm.
23  """  """
24        
25  # fix for people using python2.1  import copy, operator, types
26  from __future__ import nested_scopes  import re
   
 import copy, operator  
27    
28  from Thuban import _  from Thuban import _
29    
 import types  
   
30  from messages import \  from messages import \
31      LAYER_PROJECTION_CHANGED, \      LAYER_PROJECTION_CHANGED, \
32      LAYER_LEGEND_CHANGED, \      LAYER_LEGEND_CHANGED, \
33      LAYER_VISIBILITY_CHANGED      LAYER_VISIBILITY_CHANGED,\
34        CLASS_CHANGED
35    
36  from Thuban.Model.color import Color  from Thuban.Model.color import Color, Transparent, Black
37  from Thuban.Model.range import Range  from Thuban.Model.range import Range
38    
39  import Thuban.Model.layer  import Thuban.Model.layer
40    
41  class Classification:  from Thuban.Lib.connector import Publisher
42    
43    class Classification(Publisher):
44      """Encapsulates the classification of layer.      """Encapsulates the classification of layer.
45            
46      The Classification divides some kind of data into Groups which      The Classification divides some kind of data into Groups which
# Line 47  class Classification: Line 48  class Classification:
48      retrieved by matching data values to the appropriate group.      retrieved by matching data values to the appropriate group.
49      """      """
50    
51      def __init__(self, layer = None, field = None):      def __init__(self):
52          """Initialize a classification.          """Initialize a classification."""
   
         layer -- the Layer object who owns this classification  
   
         field -- the name of the data table field that  
                  is to be used to classify layer properties  
         """  
53    
         self.layer = None  
         self.field = None  
         self.fieldType = None  
54          self.__groups = []          self.__groups = []
55    
         self.__setLayerLock = False  
   
56          self.SetDefaultGroup(ClassGroupDefault())          self.SetDefaultGroup(ClassGroupDefault())
57    
         self.SetLayer(layer)  
         self.SetField(field)  
   
58      def __iter__(self):      def __iter__(self):
59          return ClassIterator(self.__groups)          return ClassIterator(self.__groups)
60    
61      def __deepcopy__(self, memo):      def __deepcopy__(self, memo):
62          clazz = Classification()          clazz = Classification()
63    
         # note: the only thing that isn't copied is the layer reference  
         clazz.field = self.field  
         clazz.fieldType = self.fieldType  
64          clazz.__groups[0] = copy.deepcopy(self.__groups[0])          clazz.__groups[0] = copy.deepcopy(self.__groups[0])
65    
66          for i in range(1, len(self.__groups)):          for i in range(1, len(self.__groups)):
# Line 86  class Classification: Line 70  class Classification:
70    
71      def __SendNotification(self):      def __SendNotification(self):
72          """Notify the layer that this class has changed."""          """Notify the layer that this class has changed."""
73          if self.layer is not None:          self.issue(CLASS_CHANGED)
             self.layer.ClassChanged()  
       
     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()  
   
     def GetField(self):  
         """Return the name of the field."""  
         return self.field  
   
     def GetFieldType(self):  
         """Return the field type."""  
         return self.fieldType  
   
     def SetFieldType(self, type):  
         """Set the type of the field used by this classification.  
   
         A ValueError is raised if the owning layer is not None and  
         'type' is different from the current field type.  
         """  
   
         if type != self.fieldType:  
             if self.layer is not None:  
                 raise ValueError()  
             else:  
                 self.fieldType = type  
                 self.__SendNotification()  
   
     def SetLayer(self, layer):  
         """Set the owning Layer of this classification.  
   
         A ValueError exception will be thrown either the field or  
         field type mismatch the information in the layer's table.  
         """  
   
         # prevent infinite recursion when calling SetClassification()  
         if self.__setLayerLock: return  
   
         self.__setLayerLock = True  
   
         if layer is None:  
             if self.layer is not None:  
                 l = self.layer  
                 self.layer = None  
                 l.SetClassification(None)  
         else:  
             assert isinstance(layer, Thuban.Model.layer.Layer)  
   
             old_layer = self.layer  
   
             self.layer = layer  
74    
75              try:      def __getattr__(self, attr):
76                  self.SetField(self.GetField()) # this sync's the fieldType          """Generate the compiled classification on demand"""
77              except ValueError:          if attr == "_compiled_classification":
78                  self.layer = old_layer              self._compile_classification()
79                  self.__setLayerLock = False              return self._compiled_classification
80                  raise ValueError          raise AttributeError(attr)
81    
82        def _compile_classification(self):
83            """Generate the compiled classification
84    
85            The compiled classification is a more compact representation of
86            the classification groups that is also more efficient for
87            performing the classification.
88    
89            The compiled classification is a list of tuples. The first
90            element of the tuple is a string which describes the rest of the
91            tuple. There are two kinds of tuples:
92    
93              'singletons'
94    
95                The second element of the tuple is a dictionary which
96                combines several consecutive ClassGroupSingleton instances.
97                The dictionary maps the values of the singletons (as
98                returned by the GetValue() method) to the corresponding
99                group.
100    
101              'range'
102    
103                The tuple describes a ClassGroupRange instance. The tuples
104                second element is a tuple fo the form (lfunc, min, max,
105                rfunc, group) where group is the original group object,
106                lfunc and rfuct are comparison functions and min and max are
107                lower and upper bounds of the range. Given a value and such
108                a tuple the group matches if and only if
109    
110                    lfunc(min, value) and rfunc(max, value)
111    
112                is true.
113    
114              'pattern'
115                
116                The tuple contains the compiled regular expression object and
117                the original group object.
118    
119            The compiled classification is bound to
120            self._compile_classification.
121            """
122            compiled = []
123            for group in self.__groups[1:]:
124                if isinstance(group, ClassGroupSingleton):
125                    if not compiled or compiled[-1][0] != "singletons":
126                        compiled.append(("singletons", {}))
127                    compiled[-1][1].setdefault(group.GetValue(), group)
128                elif isinstance(group, ClassGroupPattern):
129                    pattern = re.compile(group.GetPattern())
130                    compiled.append(("pattern", (pattern, group)))
131                elif isinstance(group, ClassGroupRange):
132                    left, min, max, right = group.GetRangeTuple()
133                    if left == "[":
134                        lfunc = operator.le
135                    elif left == "]":
136                        lfunc = operator.lt
137                    if right == "[":
138                        rfunc = operator.gt
139                    elif right == "]":
140                        rfunc = operator.ge
141                    compiled.append(("range", (lfunc, min, max, rfunc, group)))
142              else:              else:
143                  self.layer.SetClassification(self)                  raise TypeError("Unknown group type %s", group)
144            self._compiled_classification = compiled
145    
146          self.__setLayerLock = False      def _clear_compiled_classification(self):
147            """Reset the compiled classification.
148    
149      def GetLayer(self):          If will be created on demand when self._compiled_classification
150          """Return the parent layer."""          is accessed again.
         return self.layer  
151    
152            Call this method whenever self.__groups is modified.
153            """
154            try:
155                del self._compiled_classification
156            except:
157                pass
158    
159      #      #
160      # these SetDefault* methods are really only provided for      # these SetDefault* methods are really only provided for
# Line 197  class Classification: Line 167  class Classification:
167    
168          fill -- a Color object.          fill -- a Color object.
169          """          """
         assert isinstance(fill, Color)  
170          self.GetDefaultGroup().GetProperties().SetFill(fill)          self.GetDefaultGroup().GetProperties().SetFill(fill)
171          self.__SendNotification()          self.__SendNotification()
172                    
# Line 210  class Classification: Line 179  class Classification:
179    
180          color -- a Color object.          color -- a Color object.
181          """          """
         assert isinstance(color, Color)  
182          self.GetDefaultGroup().GetProperties().SetLineColor(color)          self.GetDefaultGroup().GetProperties().SetLineColor(color)
183          self.__SendNotification()          self.__SendNotification()
184                    
# Line 245  class Classification: Line 213  class Classification:
213    
214          group -- group that the value maps to.          group -- group that the value maps to.
215          """          """
   
216          assert isinstance(group, ClassGroupDefault)          assert isinstance(group, ClassGroupDefault)
217          if len(self.__groups) > 0:          if len(self.__groups) > 0:
218              self.__groups[0] = group              self.__groups[0] = group
219          else:          else:
220              self.__groups.append(group)              self.__groups.append(group)
221            self.__SendNotification()
222    
223      def GetDefaultGroup(self):      def GetDefaultGroup(self):
224          """Return the default group."""          """Return the default group."""
# Line 265  class Classification: Line 233  class Classification:
233          self.InsertGroup(self.GetNumGroups(), item)          self.InsertGroup(self.GetNumGroups(), item)
234    
235      def InsertGroup(self, index, group):      def InsertGroup(self, index, group):
           
236          assert isinstance(group, ClassGroup)          assert isinstance(group, ClassGroup)
   
237          self.__groups.insert(index + 1, group)          self.__groups.insert(index + 1, group)
238            self._clear_compiled_classification()
239          self.__SendNotification()          self.__SendNotification()
240    
241      def RemoveGroup(self, index):      def RemoveGroup(self, index):
242          return self.__groups.pop(index + 1)          """Remove the classification group with the given index"""
243            self.__groups.pop(index + 1)
244            self._clear_compiled_classification()
245            self.__SendNotification()
246    
247      def ReplaceGroup(self, index, group):      def ReplaceGroup(self, index, group):
248          assert isinstance(group, ClassGroup)          assert isinstance(group, ClassGroup)
   
249          self.__groups[index + 1] = group          self.__groups[index + 1] = group
250            self._clear_compiled_classification()
251          self.__SendNotification()          self.__SendNotification()
252    
253      def GetGroup(self, index):      def GetGroup(self, index):
# Line 289  class Classification: Line 257  class Classification:
257          """Return the number of non-default groups in the classification."""          """Return the number of non-default groups in the classification."""
258          return len(self.__groups) - 1          return len(self.__groups) - 1
259    
   
260      def FindGroup(self, value):      def FindGroup(self, value):
261          """Return the associated group, or the default group.          """Return the group that matches the value.
262    
263          Groups are checked in the order the were added to the          Groups are effectively checked in the order the were added to
264          Classification.          the Classification.
265    
266          value -- the value to classify. If there is no mapping,          value -- the value to classify. If there is no mapping or value
267                   the field is None or value is None,                   is None, return the default properties
                  return the default properties  
268          """          """
269    
270          if self.GetField() is not None and value is not None:          if value is not None:
271                for typ, params in self._compiled_classification:
272              for i in range(1, len(self.__groups)):                  if typ == "singletons":
273                  group = self.__groups[i]                      group = params.get(value)
274                  if group.Matches(value):                      if group is not None:
275                      return group                          return group
276                    elif typ == "range":
277                        lfunc, min, max, rfunc, g = params
278                        if lfunc(min, value) and rfunc(max, value):
279                            return g
280                    elif typ == "pattern":
281                        # TODO: make pattern more robust. The following chrashes
282                        # if accidently be applied on non-string columns.
283                        # Usually the UI prevents this.
284                        p, g = params
285                        if p.match(value):
286                            return g
287    
288          return self.GetDefaultGroup()          return self.GetDefaultGroup()
289    
# Line 328  class Classification: Line 305  class Classification:
305          items = []          items = []
306    
307          def build_color_item(text, color):          def build_color_item(text, color):
308              if color is Color.Transparent:              if color is Transparent:
309                  return ("%s: %s" % (text, _("None")), None)                  return ("%s: %s" % (text, _("None")), None)
310    
311              return ("%s: (%.3f, %.3f, %.3f)" %              return ("%s: (%.3f, %.3f, %.3f)" %
# Line 348  class Classification: Line 325  class Classification:
325              i.append(build_color_item(_("Line Color"), v))              i.append(build_color_item(_("Line Color"), v))
326              v = props.GetLineWidth()              v = props.GetLineWidth()
327              i.append(_("Line Width: %s") % v)              i.append(_("Line Width: %s") % v)
328    
329                # Note: Size is owned by all properties, so
330                # a size will also appear where it does not
331                # make sense like for lines and polygons.
332                v = props.GetSize()
333                i.append(_("Size: %s") % v)
334    
335              v = props.GetFill()              v = props.GetFill()
336              i.append(build_color_item(_("Fill"), v))              i.append(build_color_item(_("Fill"), v))
337              return (label, i)              return (label, i)
# Line 355  class Classification: Line 339  class Classification:
339          for p in self:          for p in self:
340              items.append(build_item(p, p.GetDisplayText()))              items.append(build_item(p, p.GetDisplayText()))
341    
 #           if isinstance(p, ClassGroupDefault):  
 #               items.append(build_item(self.GetDefaultGroup(), _("'DEFAULT'")))  
 #           elif isinstance(p, ClassGroupSingleton):  
 #               items.append(build_item(p, str(p.GetValue())))  
 #           elif isinstance(p, ClassGroupRange):  
 #               items.append(build_item(p, "%s - %s" %  
 #                                          (p.GetMin(), p.GetMax())))  
   
342          return (_("Classification"), items)          return (_("Classification"), items)
343    
344  class ClassIterator:  class ClassIterator:
345      """Allows the Groups in a Classifcation to be interated over.      """Allows the Groups in a Classifcation to be interated over.
346    
# Line 376  class ClassIterator: Line 352  class ClassIterator:
352          """Constructor.          """Constructor.
353    
354          default -- the default group          default -- the default group
355    
356          points -- a list of singleton groups          points -- a list of singleton groups
357    
358          ranges -- a list of range groups          ranges -- a list of range groups
359    
360          maps -- a list of map groups          maps -- a list of map groups
361          """          """
362    
363          self.data = data #[default, points, ranges, maps]          self.data = data
364          self.data_index = 0          self.data_index = 0
         #self.data_iter = iter(self.data)  
         #self.iter = None  
365    
366      def __iter__(self):      def __iter__(self):
367          return self          return self
# Line 401  class ClassIterator: Line 375  class ClassIterator:
375              d = self.data[self.data_index]              d = self.data[self.data_index]
376              self.data_index += 1              self.data_index += 1
377              return d              return d
378            
 #       if self.iter is None:  
 #           try:  
 #               self.data_item = self.data_iter.next()  
 #               self.iter = iter(self.data_item)  
 #           except TypeError:  
 #               return self.data_item  
   
 #       try:  
 #           return self.iter.next()  
 #       except StopIteration:  
 #           self.iter = None  
 #           return self.next()  
         
379  class ClassGroupProperties:  class ClassGroupProperties:
380      """Represents the properties of a single Classification Group.      """Represents the properties of a single Classification Group.
381      
382      These are used when rendering a layer."""      These are used when rendering a layer."""
383    
384        # TODO: Actually, size is only relevant for point objects.
385        # Eventually it should be spearated, e.g. when introducing symbols.
386    
387      def __init__(self, props = None):      def __init__(self, props = None):
388          """Constructor.          """Constructor.
389    
390          props -- a ClassGroupProperties object. The class is copied if          props -- a ClassGroupProperties object. The class is copied if
391                   prop is not None. Otherwise, a default set of properties                   prop is not None. Otherwise, a default set of properties
392                   is created such that: line color = Color.Black, line width = 1,                   is created such that: line color = Black, line width = 1,
393                   and fill color = Color.Transparent                   size = 5 and fill color = Transparent
394          """          """
395    
         #self.stroke = None  
         #self.strokeWidth = 0  
         #self.fill = None  
   
396          if props is not None:          if props is not None:
397              self.SetProperties(props)              self.SetProperties(props)
398          else:          else:
399              self.SetLineColor(Color.Black)              self.SetLineColor(Black)
400              self.SetLineWidth(1)              self.SetLineWidth(1)
401              self.SetFill(Color.Transparent)              self.SetSize(5)
402                self.SetFill(Transparent)
403    
404      def SetProperties(self, props):      def SetProperties(self, props):
405          """Set this class's properties to those in class props."""          """Set this class's properties to those in class props."""
# Line 446  class ClassGroupProperties: Line 407  class ClassGroupProperties:
407          assert isinstance(props, ClassGroupProperties)          assert isinstance(props, ClassGroupProperties)
408          self.SetLineColor(props.GetLineColor())          self.SetLineColor(props.GetLineColor())
409          self.SetLineWidth(props.GetLineWidth())          self.SetLineWidth(props.GetLineWidth())
410            self.SetSize(props.GetSize())
411          self.SetFill(props.GetFill())          self.SetFill(props.GetFill())
412            
413      def GetLineColor(self):      def GetLineColor(self):
414          """Return the line color as a Color object."""          """Return the line color as a Color object."""
415          return self.__stroke          return self.__stroke
# Line 458  class ClassGroupProperties: Line 420  class ClassGroupProperties:
420          color -- the color of the line. This must be a Color object.          color -- the color of the line. This must be a Color object.
421          """          """
422    
         assert isinstance(color, Color)  
423          self.__stroke = color          self.__stroke = color
424    
425      def GetLineWidth(self):      def GetLineWidth(self):
# Line 476  class ClassGroupProperties: Line 437  class ClassGroupProperties:
437    
438          self.__strokeWidth = lineWidth          self.__strokeWidth = lineWidth
439    
440        def GetSize(self):
441            """Return the size."""
442            return self.__size
443    
444        def SetSize(self, size):
445            """Set the size.
446    
447            size -- the new size. This must be > 0.
448            """
449            assert isinstance(size, types.IntType)
450            if (size < 1):
451                raise ValueError(_("size < 1"))
452    
453            self.__size = size
454    
455      def GetFill(self):      def GetFill(self):
456          """Return the fill color as a Color object."""          """Return the fill color as a Color object."""
457          return self.__fill          return self.__fill
458    
459      def SetFill(self, fill):      def SetFill(self, fill):
460          """Set the fill color.          """Set the fill color.
461    
462          fill -- the color of the fill. This must be a Color object.          fill -- the color of the fill. This must be a Color object.
463          """          """
464    
         assert isinstance(fill, Color)  
465          self.__fill = fill          self.__fill = fill
466    
467      def __eq__(self, other):      def __eq__(self, other):
# Line 501  class ClassGroupProperties: Line 476  class ClassGroupProperties:
476                   self.__stroke == other.__stroke)        \                   self.__stroke == other.__stroke)        \
477              and (self.__fill is other.__fill or          \              and (self.__fill is other.__fill or          \
478                   self.__fill == other.__fill)            \                   self.__fill == other.__fill)            \
479              and self.__strokeWidth == other.__strokeWidth              and self.__strokeWidth == other.__strokeWidth\
480                and self.__size == other.__size
481    
482      def __ne__(self, other):      def __ne__(self, other):
483          return not self.__eq__(other)          return not self.__eq__(other)
# Line 513  class ClassGroupProperties: Line 489  class ClassGroupProperties:
489          return ClassGroupProperties(self)          return ClassGroupProperties(self)
490    
491      def __repr__(self):      def __repr__(self):
492          return repr((self.__stroke, self.__strokeWidth, self.__fill))          return repr((self.__stroke, self.__strokeWidth, self.__size,
493                        self.__fill))
494    
495  class ClassGroup:  class ClassGroup:
496      """A base class for all Groups within a Classification"""      """A base class for all Groups within a Classification"""
# Line 536  class ClassGroup: Line 513  class ClassGroup:
513      def GetLabel(self):      def GetLabel(self):
514          """Return the Group's label."""          """Return the Group's label."""
515          return self.label          return self.label
516    
517      def SetLabel(self, label):      def SetLabel(self, label):
518          """Set the Group's label.          """Set the Group's label.
519    
# Line 690  class ClassGroupRange(ClassGroup): Line 667  class ClassGroupRange(ClassGroup):
667      """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
668         set of properties."""         set of properties."""
669    
670      def __init__(self, min = 0, max = 1, props = None, label = "", group=None):      def __init__(self, _range = (0,1), props = None, label = "", group=None):
671          """Constructor.          """Constructor.
672    
673          The minumum value must be strictly less than the maximum.          The minumum value must be strictly less than the maximum.
674    
675          min -- the minimum range value          _range -- either a tuple (min, max) where min < max or
676                      a Range object
         max -- the maximum range value  
677    
678          prop -- a ClassGroupProperites object. If prop is None a default          prop -- a ClassGroupProperites object. If prop is None a default
679                   set of properties is created.                   set of properties is created.
# Line 706  class ClassGroupRange(ClassGroup): Line 682  class ClassGroupRange(ClassGroup):
682          """          """
683    
684          ClassGroup.__init__(self, label, props, group)          ClassGroup.__init__(self, label, props, group)
685            self.SetRange(_range)
         #self.__min = self.__max = 0  
         #self.__range = Range("[" + repr(float(min)) + ";" +  
                                    #repr(float(max)) + "[")  
         self.SetRange(min, max)  
686    
687      def __copy__(self):      def __copy__(self):
688          return ClassGroupRange(min = self.__range,          return ClassGroupRange(self.__range,
                                max = None,  
689                                 props = self.GetProperties(),                                 props = self.GetProperties(),
690                                 label = self.GetLabel())                                 label = self.GetLabel())
691    
692      def __deepcopy__(self, memo):      def __deepcopy__(self, memo):
693          return ClassGroupRange(min = copy.copy(self.__range),          return ClassGroupRange(copy.copy(self.__range),
                                max = copy.copy(self.GetMax()),  
694                                 group = self)                                 group = self)
695    
696      def GetMin(self):      def GetMin(self):
# Line 734  class ClassGroupRange(ClassGroup): Line 704  class ClassGroupRange(ClassGroup):
704                 maximum value. Use SetRange() to change both min and max values.                 maximum value. Use SetRange() to change both min and max values.
705          """          """
706            
707          self.SetRange(min, self.__range.GetRange()[2])          self.SetRange((min, self.__range.GetRange()[2]))
708    
709      def GetMax(self):      def GetMax(self):
710          """Return the range's maximum value."""          """Return the range's maximum value."""
# Line 746  class ClassGroupRange(ClassGroup): Line 716  class ClassGroupRange(ClassGroup):
716          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
717                 minimum value. Use SetRange() to change both min and max values.                 minimum value. Use SetRange() to change both min and max values.
718          """          """
719          self.SetRange(self.__range.GetRange()[1], max)          self.SetRange((self.__range.GetRange()[1], max))
720    
721      def SetRange(self, min, max = None):      def SetRange(self, _range):
722          """Set a new range.          """Set a new range.
723    
724          Note that min must be strictly less than max.          _range -- Either a tuple (min, max) where min < max or
725                      a Range object.
726    
727          min -- the new minimum value          Raises ValueError on error.
         min -- the new maximum value  
728          """          """
729    
730          if isinstance(min, Range):          if isinstance(_range, Range):
731              self.__range = min              self.__range = _range
732            elif isinstance(_range, types.TupleType) and len(_range) == 2:
733                self.__range = Range(("[", _range[0], _range[1], "["))
734          else:          else:
735              if max is None:              raise ValueError()
                 raise ValueError()  
   
             self.__range = Range(("[", min, max, "["))  
736    
737      def GetRange(self):      def GetRange(self):
738          """Return the range as a string"""          """Return the range as a string"""
         #return (self.__min, self.__max)  
739          return self.__range.string(self.__range.GetRange())          return self.__range.string(self.__range.GetRange())
740    
741        def GetRangeTuple(self):
742            return self.__range.GetRange()
743    
744      def Matches(self, value):      def Matches(self, value):
745          """Determine if the given value lies with the current range.          """Determine if the given value lies with the current range.
746    
# Line 777  class ClassGroupRange(ClassGroup): Line 748  class ClassGroupRange(ClassGroup):
748          """          """
749    
750          return operator.contains(self.__range, value)          return operator.contains(self.__range, value)
         #return self.__min <= value < self.__max  
751    
752      def GetDisplayText(self):      def GetDisplayText(self):
753          label = self.GetLabel()          label = self.GetLabel()
754    
755          if label != "": return label          if label != "": return label
756    
         #return _("%s - %s") % (self.GetMin(), self.GetMax())  
         #return repr(self.__range)  
757          return self.__range.string(self.__range.GetRange())          return self.__range.string(self.__range.GetRange())
758    
759      def __eq__(self, other):      def __eq__(self, other):
760          return ClassGroup.__eq__(self, other) \          return ClassGroup.__eq__(self, other) \
761              and isinstance(other, ClassGroupRange) \              and isinstance(other, ClassGroupRange) \
762              and self.__range == other.__range              and self.__range == other.__range
             #and self.__min == other.__min \  
             #and self.__max == other.__max  
763    
764      def __repr__(self):      def __repr__(self):
765          return "(" + str(self.__range) + ClassGroup.__repr__(self) + ")"          return "(" + str(self.__range) + ClassGroup.__repr__(self) + ")"
766          #return "(" + repr(self.__min) + ", " + repr(self.__max) + ", " + \  
767                 #ClassGroup.__repr__(self) + ")"  class ClassGroupPattern(ClassGroup):
768        """A Group that is associated with a reg exp pattern."""
769    
770        def __init__(self, pattern = "", props = None, label = "", group = None):
771            """Constructor.
772    
773            pattern -- the associated pattern.
774    
775            props   -- a ClassGroupProperites object. If props is None a default
776                       set of properties is created.
777    
778            label   -- a label for this group.
779            """
780            ClassGroup.__init__(self, label, props, group)
781    
782            self.SetPattern(pattern)
783    
784        def __copy__(self):
785            return ClassGroupPattern(self.GetPattern(),
786                                       self.GetProperties(),
787                                       self.GetLabel())
788    
789        def __deepcopy__(self, memo):
790            return ClassGroupPattern(self.GetPattern(), group = self)
791    
792        def GetPattern(self):
793            """Return the associated pattern."""
794            return self.__pattern
795    
796        def SetPattern(self, pattern):
797            """Associate this Group with the given pattern."""
798            self.__pattern = pattern
799    
800        def Matches(self, pattern):
801            """Check if the given pattern matches the associated Group pattern."""
802    
803            """Returns True if the value matches, False otherwise."""
804    
805            if re.match(self.__pattern, pattern):
806                return True
807            else:
808                return False
809    
810        def GetDisplayText(self):
811            label = self.GetLabel()
812    
813            if label != "": return label
814    
815            return str(self.GetPattern())
816    
817        def __eq__(self, other):
818            return ClassGroup.__eq__(self, other) \
819                and isinstance(other, ClassGroupPattern) \
820                and self.__pattern == other.__pattern
821    
822        def __repr__(self):
823            return "(" + repr(self.__pattern) + ", " + ClassGroup.__repr__(self) + ")"
824    
825  class ClassGroupMap(ClassGroup):  class ClassGroupMap(ClassGroup):
826      """Currently, this class is not used."""      """Currently, this class is not used."""

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26