/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/Model/classification.py
ViewVC logotype

Annotation of /branches/WIP-pyshapelib-bramz/Thuban/Model/classification.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1249 - (hide annotations)
Fri Jun 20 09:27:19 2003 UTC (21 years, 8 months ago) by jonathan
Original Path: trunk/thuban/Thuban/Model/classification.py
File MIME type: text/x-python
File size: 24595 byte(s)
Remove "from __future__"
        import statement since python 2.2 is the earliest supported
        version.

1 bh 453 # Copyright (c) 2001, 2003 by Intevation GmbH
2 jonathan 371 # Authors:
3     # Jonathan Coles <[email protected]>
4     #
5     # This program is free software under the GPL (>=v2)
6     # Read the file COPYING coming with Thuban for details.
7    
8     __version__ = "$Revision$"
9    
10     """
11     A Classification provides a mapping from an input value
12     to data. This mapping can be specified in two ways.
13     First, specific values can be associated with data.
14     Second, ranges can be associated with data such that if
15     an input value falls with a range that data is returned.
16 jonathan 388 If no mapping can be found then default data will
17 jonathan 371 be returned. Input values must be hashable objects
18    
19 jonathan 613 See the description of FindGroup() for more information
20 jonathan 371 on the mapping algorithm.
21     """
22    
23 jonathan 1249 import copy, operator, types
24 jonathan 397
25 jonathan 613 from Thuban import _
26    
27     from messages import \
28     LAYER_PROJECTION_CHANGED, \
29     LAYER_LEGEND_CHANGED, \
30     LAYER_VISIBILITY_CHANGED
31 jonathan 388
32 jonathan 381 from Thuban.Model.color import Color
33 jonathan 873 from Thuban.Model.range import Range
34 jan 374
35 jonathan 436 import Thuban.Model.layer
36    
37 jonathan 371 class Classification:
38 jonathan 613 """Encapsulates the classification of layer.
39    
40     The Classification divides some kind of data into Groups which
41     are associated with properties. Later the properties can be
42     retrieved by matching data values to the appropriate group.
43     """
44 jonathan 371
45 jonathan 410 def __init__(self, layer = None, field = None):
46 jonathan 371 """Initialize a classification.
47    
48 jonathan 613 layer -- the Layer object who owns this classification
49 jonathan 388
50 jonathan 613 field -- the name of the data table field that
51     is to be used to classify layer properties
52 jonathan 371 """
53    
54 jonathan 462 self.layer = None
55     self.field = None
56     self.fieldType = None
57 jonathan 613 self.__groups = []
58 jonathan 436
59 jonathan 528 self.__setLayerLock = False
60    
61 jonathan 436 self.SetDefaultGroup(ClassGroupDefault())
62 jonathan 491
63 jonathan 462 self.SetLayer(layer)
64 jonathan 436 self.SetField(field)
65    
66 jonathan 428 def __iter__(self):
67 jonathan 613 return ClassIterator(self.__groups)
68 jonathan 428
69 jonathan 613 def __deepcopy__(self, memo):
70     clazz = Classification()
71    
72 jonathan 627 # note: the only thing that isn't copied is the layer reference
73     clazz.field = self.field
74     clazz.fieldType = self.fieldType
75 jonathan 613 clazz.__groups[0] = copy.deepcopy(self.__groups[0])
76    
77     for i in range(1, len(self.__groups)):
78     clazz.__groups.append(copy.deepcopy(self.__groups[i]))
79    
80     return clazz
81    
82 jonathan 491 def __SendNotification(self):
83     """Notify the layer that this class has changed."""
84     if self.layer is not None:
85     self.layer.ClassChanged()
86 jonathan 410
87 jonathan 491 def SetField(self, field):
88 jonathan 371 """Set the name of the data table field to use.
89    
90 jonathan 613 If there is no layer then the field type is set to None,
91     otherwise the layer is queried to find the type of the
92     field data
93 jonathan 479
94 jonathan 613 field -- if None then all values map to the default data
95 jonathan 371 """
96    
97 jonathan 436 if field == "":
98     field = None
99    
100 jonathan 462
101 jonathan 491 if field is None:
102     if self.layer is not None:
103     self.fieldType = None
104 jonathan 462 else:
105 jonathan 491 if self.layer is not None:
106     fieldType = self.layer.GetFieldType(field)
107     if fieldType is None:
108     raise ValueError("'%s' was not found in the layer's table."
109     % self.field)
110 jonathan 462
111 jonathan 491 #
112     # unfortunately we cannot call SetFieldType() because it
113     # requires the layer to be None
114     #
115     self.fieldType = fieldType
116     #self.SetFieldType(fieldType)
117 jonathan 462
118 jonathan 491 self.field = field
119 jonathan 462
120 jonathan 491 self.__SendNotification()
121 jonathan 371
122 jonathan 388 def GetField(self):
123 jonathan 462 """Return the name of the field."""
124 jonathan 388 return self.field
125    
126 jonathan 462 def GetFieldType(self):
127     """Return the field type."""
128     return self.fieldType
129    
130     def SetFieldType(self, type):
131 jonathan 491 """Set the type of the field used by this classification.
132 jonathan 462
133 jonathan 491 A ValueError is raised if the owning layer is not None and
134     'type' is different from the current field type.
135     """
136    
137     if type != self.fieldType:
138     if self.layer is not None:
139     raise ValueError()
140     else:
141     self.fieldType = type
142     self.__SendNotification()
143    
144 jonathan 410 def SetLayer(self, layer):
145 jonathan 491 """Set the owning Layer of this classification.
146    
147 jonathan 613 A ValueError exception will be thrown either the field or
148     field type mismatch the information in the layer's table.
149 jonathan 491 """
150 jonathan 462
151 jonathan 528 # prevent infinite recursion when calling SetClassification()
152     if self.__setLayerLock: return
153    
154     self.__setLayerLock = True
155    
156 jonathan 491 if layer is None:
157     if self.layer is not None:
158     l = self.layer
159     self.layer = None
160     l.SetClassification(None)
161     else:
162 jonathan 602 assert isinstance(layer, Thuban.Model.layer.Layer)
163 jonathan 462
164 jonathan 491 old_layer = self.layer
165 jonathan 479
166 jonathan 491 self.layer = layer
167 jonathan 462
168 jonathan 491 try:
169     self.SetField(self.GetField()) # this sync's the fieldType
170     except ValueError:
171     self.layer = old_layer
172 jonathan 528 self.__setLayerLock = False
173 jonathan 491 raise ValueError
174     else:
175     self.layer.SetClassification(self)
176 jonathan 410
177 jonathan 528 self.__setLayerLock = False
178    
179 jonathan 410 def GetLayer(self):
180 jonathan 462 """Return the parent layer."""
181     return self.layer
182 jonathan 410
183 jonathan 371
184 jonathan 428 #
185     # these SetDefault* methods are really only provided for
186     # some backward compatibility. they should be considered
187     # for removal once all the classification code is finished.
188     #
189    
190 jonathan 388 def SetDefaultFill(self, fill):
191 jonathan 462 """Set the default fill color.
192    
193     fill -- a Color object.
194     """
195     self.GetDefaultGroup().GetProperties().SetFill(fill)
196 jonathan 491 self.__SendNotification()
197 jonathan 388
198     def GetDefaultFill(self):
199 jonathan 462 """Return the default fill color."""
200     return self.GetDefaultGroup().GetProperties().GetFill()
201 jonathan 388
202 jonathan 462 def SetDefaultLineColor(self, color):
203     """Set the default line color.
204    
205     color -- a Color object.
206     """
207     self.GetDefaultGroup().GetProperties().SetLineColor(color)
208 jonathan 491 self.__SendNotification()
209 jonathan 388
210 jonathan 462 def GetDefaultLineColor(self):
211     """Return the default line color."""
212     return self.GetDefaultGroup().GetProperties().GetLineColor()
213 jonathan 388
214 jonathan 462 def SetDefaultLineWidth(self, lineWidth):
215     """Set the default line width.
216    
217     lineWidth -- an integer > 0.
218     """
219 jonathan 873 assert isinstance(lineWidth, types.IntType)
220 jonathan 462 self.GetDefaultGroup().GetProperties().SetLineWidth(lineWidth)
221 jonathan 491 self.__SendNotification()
222 jonathan 388
223 jonathan 462 def GetDefaultLineWidth(self):
224     """Return the default line width."""
225     return self.GetDefaultGroup().GetProperties().GetLineWidth()
226 jonathan 388
227 jonathan 462
228 jonathan 613 #
229     # The methods that manipulate self.__groups have to be kept in
230     # sync. We store the default group in index 0 to make it
231     # convienent to iterate over the classification's groups, but
232     # from the user's perspective the first (non-default) group is
233     # at index 0 and the DefaultGroup is a special entity.
234     #
235    
236     def SetDefaultGroup(self, group):
237     """Set the group to be used when a value can't be classified.
238    
239     group -- group that the value maps to.
240     """
241    
242     assert isinstance(group, ClassGroupDefault)
243     if len(self.__groups) > 0:
244     self.__groups[0] = group
245     else:
246     self.__groups.append(group)
247    
248     def GetDefaultGroup(self):
249     """Return the default group."""
250     return self.__groups[0]
251    
252     def AppendGroup(self, item):
253     """Append a new ClassGroup item to the classification.
254    
255 jonathan 462 item -- this must be a valid ClassGroup object
256     """
257    
258 jonathan 613 self.InsertGroup(self.GetNumGroups(), item)
259 jonathan 371
260 jonathan 613 def InsertGroup(self, index, group):
261    
262     assert isinstance(group, ClassGroup)
263 jonathan 371
264 jonathan 613 self.__groups.insert(index + 1, group)
265    
266 jonathan 491 self.__SendNotification()
267 jonathan 371
268 jonathan 613 def RemoveGroup(self, index):
269     return self.__groups.pop(index + 1)
270    
271     def ReplaceGroup(self, index, group):
272     assert isinstance(group, ClassGroup)
273    
274     self.__groups[index + 1] = group
275    
276     self.__SendNotification()
277    
278     def GetGroup(self, index):
279     return self.__groups[index + 1]
280    
281     def GetNumGroups(self):
282     """Return the number of non-default groups in the classification."""
283     return len(self.__groups) - 1
284    
285    
286     def FindGroup(self, value):
287 jonathan 462 """Return the associated group, or the default group.
288 jonathan 371
289 jonathan 613 Groups are checked in the order the were added to the
290     Classification.
291 jonathan 371
292 jonathan 613 value -- the value to classify. If there is no mapping,
293     the field is None or value is None,
294     return the default properties
295 jonathan 371 """
296    
297 jonathan 479 if self.GetField() is not None and value is not None:
298 jonathan 371
299 jonathan 613 for i in range(1, len(self.__groups)):
300     group = self.__groups[i]
301 jonathan 462 if group.Matches(value):
302     return group
303 jonathan 371
304 jonathan 462 return self.GetDefaultGroup()
305 jonathan 371
306 jonathan 462 def GetProperties(self, value):
307 jonathan 613 """Return the properties associated with the given value.
308    
309     Use this function rather than Classification.FindGroup().GetProperties()
310     since the returned group may be a ClassGroupMap which doesn't support
311     a call to GetProperties().
312     """
313 jonathan 371
314 jonathan 613 group = self.FindGroup(value)
315 jonathan 462 if isinstance(group, ClassGroupMap):
316     return group.GetPropertiesFromValue(value)
317     else:
318     return group.GetProperties()
319 jonathan 436
320 jonathan 381 def TreeInfo(self):
321     items = []
322 jonathan 378
323 jonathan 410 def build_color_item(text, color):
324 jonathan 609 if color is Color.Transparent:
325 jonathan 410 return ("%s: %s" % (text, _("None")), None)
326 jonathan 381
327 jonathan 410 return ("%s: (%.3f, %.3f, %.3f)" %
328     (text, color.red, color.green, color.blue),
329     color)
330 jonathan 381
331 jonathan 436 def build_item(group, string):
332     label = group.GetLabel()
333 jonathan 410 if label == "":
334     label = string
335     else:
336     label += " (%s)" % string
337    
338 jonathan 436 props = group.GetProperties()
339 jonathan 381 i = []
340 jonathan 462 v = props.GetLineColor()
341     i.append(build_color_item(_("Line Color"), v))
342     v = props.GetLineWidth()
343     i.append(_("Line Width: %s") % v)
344 jonathan 436 v = props.GetFill()
345 jonathan 410 i.append(build_color_item(_("Fill"), v))
346     return (label, i)
347 jonathan 388
348 jonathan 428 for p in self:
349 jonathan 613 items.append(build_item(p, p.GetDisplayText()))
350 jonathan 388
351 jonathan 613 # if isinstance(p, ClassGroupDefault):
352     # items.append(build_item(self.GetDefaultGroup(), _("'DEFAULT'")))
353     # elif isinstance(p, ClassGroupSingleton):
354     # items.append(build_item(p, str(p.GetValue())))
355     # elif isinstance(p, ClassGroupRange):
356     # items.append(build_item(p, "%s - %s" %
357     # (p.GetMin(), p.GetMax())))
358    
359 jonathan 436 return (_("Classification"), items)
360 jonathan 381
361 jonathan 428 class ClassIterator:
362 jonathan 462 """Allows the Groups in a Classifcation to be interated over.
363 jonathan 388
364 jonathan 462 The items are returned in the following order:
365     default data, singletons, ranges, maps
366     """
367 jonathan 428
368 jonathan 462 def __init__(self, data): #default, points, ranges, maps):
369     """Constructor.
370    
371     default -- the default group
372    
373     points -- a list of singleton groups
374    
375     ranges -- a list of range groups
376    
377     maps -- a list of map groups
378     """
379    
380     self.data = data #[default, points, ranges, maps]
381     self.data_index = 0
382     #self.data_iter = iter(self.data)
383     #self.iter = None
384    
385 jonathan 428 def __iter__(self):
386     return self
387    
388     def next(self):
389 jonathan 462 """Return the next item."""
390 jonathan 428
391 jonathan 462 if self.data_index >= len(self.data):
392     raise StopIteration
393     else:
394     d = self.data[self.data_index]
395     self.data_index += 1
396     return d
397    
398     # if self.iter is None:
399     # try:
400     # self.data_item = self.data_iter.next()
401     # self.iter = iter(self.data_item)
402     # except TypeError:
403     # return self.data_item
404    
405     # try:
406     # return self.iter.next()
407     # except StopIteration:
408     # self.iter = None
409     # return self.next()
410 jonathan 428
411 jonathan 436 class ClassGroupProperties:
412 jonathan 462 """Represents the properties of a single Classification Group.
413    
414     These are used when rendering a layer."""
415 jonathan 388
416 jonathan 462 def __init__(self, props = None):
417     """Constructor.
418 jonathan 410
419 jonathan 462 props -- a ClassGroupProperties object. The class is copied if
420     prop is not None. Otherwise, a default set of properties
421 jonathan 479 is created such that: line color = Color.Black, line width = 1,
422 jonathan 609 and fill color = Color.Transparent
423 jonathan 462 """
424    
425 jonathan 637 #self.stroke = None
426     #self.strokeWidth = 0
427     #self.fill = None
428 jonathan 462
429     if props is not None:
430     self.SetProperties(props)
431 jonathan 410 else:
432 jonathan 484 self.SetLineColor(Color.Black)
433 jonathan 462 self.SetLineWidth(1)
434 jonathan 609 self.SetFill(Color.Transparent)
435 jonathan 410
436 jonathan 462 def SetProperties(self, props):
437     """Set this class's properties to those in class props."""
438    
439 jonathan 602 assert isinstance(props, ClassGroupProperties)
440 jonathan 462 self.SetLineColor(props.GetLineColor())
441     self.SetLineWidth(props.GetLineWidth())
442     self.SetFill(props.GetFill())
443    
444     def GetLineColor(self):
445     """Return the line color as a Color object."""
446 jonathan 678 return self.__stroke
447 jonathan 388
448 jonathan 462 def SetLineColor(self, color):
449     """Set the line color.
450 jonathan 388
451 jonathan 462 color -- the color of the line. This must be a Color object.
452     """
453 jonathan 388
454 jonathan 678 self.__stroke = color
455 jonathan 410
456 jonathan 462 def GetLineWidth(self):
457     """Return the line width."""
458 jonathan 678 return self.__strokeWidth
459 jonathan 388
460 jonathan 462 def SetLineWidth(self, lineWidth):
461     """Set the line width.
462    
463     lineWidth -- the new line width. This must be > 0.
464     """
465 jonathan 873 assert isinstance(lineWidth, types.IntType)
466 jonathan 462 if (lineWidth < 1):
467     raise ValueError(_("lineWidth < 1"))
468    
469 jonathan 678 self.__strokeWidth = lineWidth
470 jonathan 462
471 jonathan 388 def GetFill(self):
472 jonathan 462 """Return the fill color as a Color object."""
473 jonathan 678 return self.__fill
474 jonathan 388
475     def SetFill(self, fill):
476 jonathan 462 """Set the fill color.
477    
478     fill -- the color of the fill. This must be a Color object.
479     """
480    
481 jonathan 678 self.__fill = fill
482 jonathan 388
483 jonathan 479 def __eq__(self, other):
484     """Return true if 'props' has the same attributes as this class"""
485 jonathan 436
486 jonathan 678 #
487     # using 'is' over '==' results in a huge performance gain
488     # in the renderer
489     #
490 jonathan 479 return isinstance(other, ClassGroupProperties) \
491 jonathan 678 and (self.__stroke is other.__stroke or \
492     self.__stroke == other.__stroke) \
493     and (self.__fill is other.__fill or \
494     self.__fill == other.__fill) \
495     and self.__strokeWidth == other.__strokeWidth
496 jonathan 479
497     def __ne__(self, other):
498     return not self.__eq__(other)
499    
500 jonathan 484 def __copy__(self):
501     return ClassGroupProperties(self)
502    
503 jonathan 602 def __deepcopy__(self):
504     return ClassGroupProperties(self)
505    
506 jonathan 681 def __repr__(self):
507     return repr((self.__stroke, self.__strokeWidth, self.__fill))
508    
509 jonathan 436 class ClassGroup:
510 jonathan 462 """A base class for all Groups within a Classification"""
511 jonathan 436
512 jonathan 637 def __init__(self, label = "", props = None, group = None):
513 jonathan 462 """Constructor.
514 jonathan 436
515 jonathan 462 label -- A string representing the Group's label
516     """
517    
518 jonathan 637 if group is not None:
519     self.SetLabel(copy.copy(group.GetLabel()))
520     self.SetProperties(copy.copy(group.GetProperties()))
521     self.SetVisible(group.IsVisible())
522     else:
523     self.SetLabel(label)
524     self.SetProperties(props)
525     self.SetVisible(True)
526 jonathan 462
527 jonathan 388 def GetLabel(self):
528 jonathan 462 """Return the Group's label."""
529 jonathan 388 return self.label
530    
531     def SetLabel(self, label):
532 jonathan 462 """Set the Group's label.
533    
534     label -- a string representing the Group's label. This must
535     not be None.
536     """
537 jonathan 873 assert isinstance(label, types.StringTypes)
538 jonathan 388 self.label = label
539    
540 jonathan 544 def GetDisplayText(self):
541 jonathan 602 assert False, "GetDisplay must be overridden by subclass!"
542 jonathan 544 return ""
543    
544 jonathan 436 def Matches(self, value):
545 jonathan 462 """Determines if this Group is associated with the given value.
546    
547 jonathan 479 Returns False. This needs to be overridden by all subclasses.
548 jonathan 462 """
549 jonathan 602 assert False, "GetMatches must be overridden by subclass!"
550 jonathan 479 return False
551 jonathan 436
552 jonathan 462 def GetProperties(self):
553 jonathan 637 """Return the properties associated with the given value."""
554 jonathan 462
555 jonathan 637 return self.prop
556    
557     def SetProperties(self, prop):
558     """Set the properties associated with this Group.
559    
560     prop -- a ClassGroupProperties object. if prop is None,
561     a default set of properties is created.
562 jonathan 462 """
563 jonathan 637
564     if prop is None: prop = ClassGroupProperties()
565     assert isinstance(prop, ClassGroupProperties)
566     self.prop = prop
567    
568     def IsVisible(self):
569     return self.visible
570    
571     def SetVisible(self, visible):
572     self.visible = visible
573    
574     def __eq__(self, other):
575     return isinstance(other, ClassGroup) \
576 jonathan 681 and self.label == other.label \
577 jonathan 637 and self.GetProperties() == other.GetProperties()
578    
579     def __ne__(self, other):
580     return not self.__eq__(other)
581    
582 jonathan 681 def __repr__(self):
583 jonathan 689 return repr(self.label) + ", " + repr(self.GetProperties())
584 jonathan 410
585 jonathan 436 class ClassGroupSingleton(ClassGroup):
586 jonathan 462 """A Group that is associated with a single value."""
587 jonathan 410
588 jonathan 637 def __init__(self, value = 0, props = None, label = "", group = None):
589 jonathan 462 """Constructor.
590    
591     value -- the associated value.
592    
593     prop -- a ClassGroupProperites object. If prop is None a default
594     set of properties is created.
595    
596     label -- a label for this group.
597     """
598 jonathan 637 ClassGroup.__init__(self, label, props, group)
599 jonathan 410
600 jonathan 436 self.SetValue(value)
601 jonathan 410
602 jonathan 436 def __copy__(self):
603 jonathan 479 return ClassGroupSingleton(self.GetValue(),
604     self.GetProperties(),
605     self.GetLabel())
606 jonathan 436
607 jonathan 484 def __deepcopy__(self, memo):
608 jonathan 637 return ClassGroupSingleton(self.GetValue(), group = self)
609 jonathan 484
610 jonathan 410 def GetValue(self):
611 jonathan 462 """Return the associated value."""
612 jonathan 678 return self.__value
613 jonathan 410
614     def SetValue(self, value):
615 jonathan 462 """Associate this Group with the given value."""
616 jonathan 678 self.__value = value
617 jonathan 410
618 jonathan 436 def Matches(self, value):
619 jonathan 462 """Determine if the given value matches the associated Group value."""
620    
621     """Returns True if the value matches, False otherwise."""
622    
623 jonathan 678 return self.__value == value
624 jonathan 410
625 jonathan 544 def GetDisplayText(self):
626     label = self.GetLabel()
627    
628     if label != "": return label
629    
630     return str(self.GetValue())
631    
632 jonathan 479 def __eq__(self, other):
633 jonathan 637 return ClassGroup.__eq__(self, other) \
634     and isinstance(other, ClassGroupSingleton) \
635 jonathan 678 and self.__value == other.__value
636 jonathan 436
637 jonathan 681 def __repr__(self):
638 jonathan 689 return "(" + repr(self.__value) + ", " + ClassGroup.__repr__(self) + ")"
639 jonathan 681
640 jonathan 479 class ClassGroupDefault(ClassGroup):
641 jonathan 462 """The default Group. When values do not match any other
642     Group within a Classification, the properties from this
643     class are used."""
644    
645 jonathan 637 def __init__(self, props = None, label = "", group = None):
646 jonathan 462 """Constructor.
647    
648     prop -- a ClassGroupProperites object. If prop is None a default
649     set of properties is created.
650    
651     label -- a label for this group.
652     """
653    
654 jonathan 637 ClassGroup.__init__(self, label, props, group)
655 jonathan 436
656     def __copy__(self):
657 jonathan 479 return ClassGroupDefault(self.GetProperties(), self.GetLabel())
658 jonathan 436
659 jonathan 484 def __deepcopy__(self, memo):
660 jonathan 637 return ClassGroupDefault(label = self.GetLabel(), group = self)
661 jonathan 484
662 jonathan 479 def Matches(self, value):
663     return True
664    
665 jonathan 544 def GetDisplayText(self):
666     label = self.GetLabel()
667    
668     if label != "": return label
669    
670 jonathan 613 return _("DEFAULT")
671 jonathan 544
672 jonathan 479 def __eq__(self, other):
673 jonathan 637 return ClassGroup.__eq__(self, other) \
674     and isinstance(other, ClassGroupDefault) \
675 jonathan 479 and self.GetProperties() == other.GetProperties()
676    
677 jonathan 681 def __repr__(self):
678     return "(" + ClassGroup.__repr__(self) + ")"
679    
680 jonathan 436 class ClassGroupRange(ClassGroup):
681 jonathan 462 """A Group that represents a range of values that map to the same
682     set of properties."""
683 jonathan 436
684 jonathan 637 def __init__(self, min = 0, max = 1, props = None, label = "", group=None):
685 jonathan 462 """Constructor.
686    
687     The minumum value must be strictly less than the maximum.
688    
689     min -- the minimum range value
690    
691     max -- the maximum range value
692    
693     prop -- a ClassGroupProperites object. If prop is None a default
694     set of properties is created.
695    
696     label -- a label for this group.
697     """
698    
699 jonathan 643 ClassGroup.__init__(self, label, props, group)
700 jonathan 436
701 jonathan 873 #self.__min = self.__max = 0
702     #self.__range = Range("[" + repr(float(min)) + ";" +
703     #repr(float(max)) + "[")
704 jonathan 410 self.SetRange(min, max)
705    
706 jonathan 436 def __copy__(self):
707 jonathan 873 return ClassGroupRange(min = self.__range,
708     max = None,
709     props = self.GetProperties(),
710     label = self.GetLabel())
711 jonathan 436
712 jonathan 484 def __deepcopy__(self, memo):
713 jonathan 873 return ClassGroupRange(min = copy.copy(self.__range),
714     max = copy.copy(self.GetMax()),
715 jonathan 637 group = self)
716 jonathan 484
717 jonathan 410 def GetMin(self):
718 jonathan 462 """Return the range's minimum value."""
719 jonathan 873 return self.__range.GetRange()[1]
720 jonathan 410
721     def SetMin(self, min):
722 jonathan 462 """Set the range's minimum value.
723    
724     min -- the new minimum. Note that this must be less than the current
725     maximum value. Use SetRange() to change both min and max values.
726     """
727    
728 jonathan 873 self.SetRange(min, self.__range.GetRange()[2])
729 jonathan 410
730     def GetMax(self):
731 jonathan 462 """Return the range's maximum value."""
732 jonathan 873 return self.__range.GetRange()[2]
733 jonathan 410
734     def SetMax(self, max):
735 jonathan 462 """Set the range's maximum value.
736    
737     max -- the new maximum. Note that this must be greater than the current
738     minimum value. Use SetRange() to change both min and max values.
739     """
740 jonathan 873 self.SetRange(self.__range.GetRange()[1], max)
741 jonathan 410
742 jonathan 873 def SetRange(self, min, max = None):
743 jonathan 462 """Set a new range.
744    
745     Note that min must be strictly less than max.
746    
747     min -- the new minimum value
748     min -- the new maximum value
749     """
750    
751 jonathan 873 if isinstance(min, Range):
752     self.__range = min
753     else:
754     if max is None:
755     raise ValueError()
756 jonathan 410
757 jonathan 960 self.__range = Range(("[", min, max, "["))
758 jonathan 873
759 jonathan 410 def GetRange(self):
760 jonathan 873 """Return the range as a string"""
761     #return (self.__min, self.__max)
762     return self.__range.string(self.__range.GetRange())
763 jonathan 410
764 jonathan 436 def Matches(self, value):
765 jonathan 462 """Determine if the given value lies with the current range.
766    
767     The following check is used: min <= value < max.
768     """
769    
770 jonathan 873 return operator.contains(self.__range, value)
771     #return self.__min <= value < self.__max
772 jonathan 410
773 jonathan 544 def GetDisplayText(self):
774     label = self.GetLabel()
775    
776     if label != "": return label
777    
778 jonathan 873 #return _("%s - %s") % (self.GetMin(), self.GetMax())
779     #return repr(self.__range)
780     return self.__range.string(self.__range.GetRange())
781 jonathan 544
782 jonathan 479 def __eq__(self, other):
783 jonathan 637 return ClassGroup.__eq__(self, other) \
784     and isinstance(other, ClassGroupRange) \
785 jonathan 873 and self.__range == other.__range
786     #and self.__min == other.__min \
787     #and self.__max == other.__max
788 jonathan 479
789 jonathan 681 def __repr__(self):
790 jonathan 873 return "(" + str(self.__range) + ClassGroup.__repr__(self) + ")"
791     #return "(" + repr(self.__min) + ", " + repr(self.__max) + ", " + \
792     #ClassGroup.__repr__(self) + ")"
793 jonathan 681
794 jonathan 436 class ClassGroupMap(ClassGroup):
795 jonathan 462 """Currently, this class is not used."""
796 jonathan 436
797 jonathan 410 FUNC_ID = "id"
798    
799 jonathan 436 def __init__(self, map_type = FUNC_ID, func = None, prop = None, label=""):
800 jonathan 462 ClassGroup.__init__(self, label)
801 jonathan 410
802     self.map_type = map_type
803     self.func = func
804    
805     if self.func is None:
806     self.func = func_id
807    
808     def Map(self, value):
809     return self.func(value)
810    
811 jonathan 462 def GetProperties(self):
812     return None
813    
814     def GetPropertiesFromValue(self, value):
815     pass
816    
817 jonathan 544 def GetDisplayText(self):
818     return "Map: " + self.map_type
819    
820 jonathan 410 #
821     # built-in mappings
822     #
823     def func_id(value):
824     return value
825    

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26