/[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 1176 - (hide annotations)
Thu Jun 12 15:46:22 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: 24674 byte(s)
Removed assert statements that tested if the variable was an instance of Color.

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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26