/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/classgen.py
ViewVC logotype

Annotation of /branches/WIP-pyshapelib-bramz/Thuban/UI/classgen.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1122 - (hide annotations)
Mon Jun 2 13:47:01 2003 UTC (21 years, 9 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/classgen.py
File MIME type: text/x-python
File size: 30675 byte(s)
(GenQuantilesPanel.GetList): Resource
acquisition has to happen before the try in a try-finally.

1 jonathan 607 # Copyright (c) 2003 by Intevation GmbH
2     # 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 jonathan 677 import sys
9    
10 jonathan 607 from Thuban import _
11    
12     from wxPython.wx import *
13    
14 bh 907 from Thuban.Model.classification import ClassGroupProperties
15 jonathan 607
16 bh 907 from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_DOUBLE, \
17 jonathan 607 FIELDTYPE_STRING
18    
19 jonathan 877 from Thuban.Model.range import Range
20 jonathan 607
21 jonathan 877 import classifier, resource
22 jonathan 629
23 jonathan 1100 from Thuban.Model.classgen import \
24     GenUniformDistribution, GenSingletonsFromList, GenQuantiles, \
25 jonathan 877 CustomRamp, GreyRamp, RedRamp, GreenRamp, BlueRamp, GreenToRedRamp, \
26     HotToColdRamp
27 jonathan 649
28     USEALL_BMP = "group_use_all"
29     USE_BMP = "group_use"
30     USENOT_BMP = "group_use_not"
31     USENONE_BMP = "group_use_none"
32    
33 jonathan 635 GENCOMBOSTR_UNIFORM = _("Uniform Distribution")
34     GENCOMBOSTR_UNIQUE = _("Unique Values")
35 jonathan 877 GENCOMBOSTR_QUANTILES = _("Quantiles from Table")
36 jonathan 629
37 jonathan 649 PROPCOMBOSTR_CUSTOM = _("Custom Ramp")
38     PROPCOMBOSTR_GREY = _("Grey Ramp")
39     PROPCOMBOSTR_RED = _("Red Ramp")
40     PROPCOMBOSTR_GREEN = _("Green Ramp")
41     PROPCOMBOSTR_BLUE = _("Blue Ramp")
42 jonathan 877 PROPCOMBOSTR_GREEN2RED = _("Green-to-Red Ramp")
43 jonathan 649 PROPCOMBOSTR_HOT2COLD = _("Hot-to-Cold Ramp")
44 jonathan 635
45 jonathan 877 ID_CLASSGEN_GENCOMBO = 4007
46     ID_CLASSGEN_PROPCOMBO = 4008
47    
48 jonathan 607 class ClassGenDialog(wxDialog):
49 bh 834
50 jonathan 629 def __init__(self, parent, layer, fieldName):
51     """Inialize the class generating dialog.
52    
53     parent -- this must be an instance of the Classifier class
54     """
55    
56 jonathan 607 wxDialog.__init__(self, parent, -1, _("Generate Classification"),
57     style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
58 bh 834
59 jonathan 629 self.parent = parent
60 jonathan 877 self.layer = layer
61 jonathan 607 self.clazz = None
62    
63 bh 834 col = layer.table.Column(fieldName)
64     self.type = col.type
65 jonathan 607
66 jonathan 877 self.fieldName = fieldName
67     self.fieldType = self.type
68    
69     self.curGenPanel = None
70    
71     self.genpanels = []
72    
73 jonathan 629 #############
74     # we need to create genButton first because when we create the
75     # panels they will call AllowGenerate() which uses genButton.
76     #
77 jonathan 812 self.genButton = wxButton(self, wxID_OK, _("Generate"))
78     self.genButton.SetDefault()
79 frank 978 self.cancelButton = wxButton(self, wxID_CANCEL, _("Close"))
80    
81 jonathan 812 self.genChoice = wxChoice(self, ID_CLASSGEN_GENCOMBO)
82 jonathan 607
83 jonathan 877 self.genpanels.append((GENCOMBOSTR_UNIQUE, GenUniquePanel))
84     if self.type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):
85     self.genpanels.append((GENCOMBOSTR_UNIFORM, GenUniformPanel))
86     self.genpanels.append((GENCOMBOSTR_QUANTILES, GenQuantilesPanel))
87 jonathan 812
88 jonathan 877 for name, clazz in self.genpanels:
89     self.genChoice.Append(name, [clazz, None])
90 jonathan 812
91     self.genChoice.SetSelection(0)
92    
93 frank 978 for i in range(self.genChoice.GetCount()):
94     clazz, obj = self.genChoice.GetClientData(i)
95 jonathan 812
96 frank 978 if obj is None:
97     obj = clazz(self, self.layer, self.fieldName, self.fieldType)
98     obj.Hide()
99     self.genChoice.SetClientData(i, [clazz, obj])
100 jonathan 812
101    
102 jonathan 629 #############
103 jonathan 607
104 jonathan 629 sizer = wxBoxSizer(wxVERTICAL)
105    
106     sizer.Add(wxStaticText(self, -1, _("Field: %s") % fieldName),
107     0, wxALL, 4)
108     sizer.Add(wxStaticText(
109     self, -1,
110 jonathan 649 _("Data Type: %s") % classifier.Classifier.type2string[self.type]),
111 jonathan 629 0, wxALL, 4)
112    
113     psizer = wxBoxSizer(wxHORIZONTAL)
114 jonathan 635 psizer.Add(wxStaticText(self, -1, _("Generate:")),
115 jonathan 629 0, wxALIGN_CENTER_VERTICAL, 0)
116 jonathan 728 psizer.Add(self.genChoice, 1, wxALL | wxGROW, 4)
117 jonathan 629
118     sizer.Add(psizer, 0, wxALL | wxGROW, 4)
119    
120 jonathan 877 self.sizer_genPanel = wxBoxSizer(wxVERTICAL)
121     sizer.Add(self.sizer_genPanel, 1, wxGROW | wxALL, 4)
122 jonathan 629
123 jonathan 635 psizer = wxBoxSizer(wxHORIZONTAL)
124 jonathan 660 psizer.Add(wxStaticText(self, -1, _("Color Scheme:")),
125 jonathan 635 0, wxALIGN_CENTER_VERTICAL, 0)
126 frank 978
127     # Properties (Ramp) ComboBox
128     self.propCombo = wxChoice(self, ID_CLASSGEN_PROPCOMBO)
129    
130     self.propPanel = None
131     custom_ramp_panel = CustomRampPanel(self, layer.ShapeType())
132    
133     self.propCombo.Append(PROPCOMBOSTR_GREY, GreyRamp())
134     self.propCombo.Append(PROPCOMBOSTR_RED, RedRamp())
135     self.propCombo.Append(PROPCOMBOSTR_GREEN, GreenRamp())
136     self.propCombo.Append(PROPCOMBOSTR_BLUE, BlueRamp())
137     self.propCombo.Append(PROPCOMBOSTR_GREEN2RED, GreenToRedRamp())
138     self.propCombo.Append(PROPCOMBOSTR_HOT2COLD, HotToColdRamp())
139     self.propCombo.Append(PROPCOMBOSTR_CUSTOM, custom_ramp_panel)
140    
141     self.propCombo.SetSelection(0)
142    
143 jonathan 635 psizer.Add(self.propCombo, 1, wxALL | wxGROW, 4)
144     sizer.Add(psizer, 0, wxALL | wxGROW, 4)
145 jonathan 629
146 jonathan 812 sizer.Add(custom_ramp_panel, 1, wxGROW | wxALL, 4)
147     sizer.Show(custom_ramp_panel, False)
148 jonathan 629
149 frank 978 # Finally place the main buttons
150 jonathan 812 buttonSizer = wxBoxSizer(wxHORIZONTAL)
151 frank 978 buttonSizer.Add(self.genButton, 0, wxRIGHT|wxEXPAND, 10)
152     buttonSizer.Add(self.cancelButton, 0, wxRIGHT|wxEXPAND, 10)
153     sizer.Add(buttonSizer, 0, wxALIGN_RIGHT|wxBOTTOM|wxTOP, 10)
154 jonathan 607
155     self.SetSizer(sizer)
156     self.SetAutoLayout(True)
157     sizer.SetSizeHints(self)
158    
159 jonathan 877 self.topBox = sizer
160 jonathan 629
161 jonathan 877 self.__DoOnGenTypeSelect()
162    
163 jonathan 812 EVT_CHOICE(self, ID_CLASSGEN_GENCOMBO, self._OnGenTypeSelect)
164     EVT_CHOICE(self, ID_CLASSGEN_PROPCOMBO, self._OnPropTypeSelect)
165     EVT_BUTTON(self, wxID_OK, self.OnOK)
166     EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
167 jonathan 607
168 jonathan 877 self.__DoOnGenTypeSelect()
169 jonathan 812
170     self.genChoice.SetFocus()
171    
172 jonathan 607 def GetClassification(self):
173     return self.clazz
174    
175     def AllowGenerate(self, on):
176 jonathan 629 pass #self.genButton.Enable(on)
177 jonathan 607
178 jonathan 812 def OnOK(self, event):
179     """This is really the generate button, but we want to override
180     the wxDialog class.
181     """
182 jonathan 607
183 jonathan 728 index = self.genChoice.GetSelection()
184 jonathan 607
185 jonathan 877 assert index != -1, "button should be disabled!"
186    
187 jonathan 728 genSel = self.genChoice.GetString(index)
188 jonathan 877 clazz, genPanel = self.genChoice.GetClientData(index)
189 jonathan 635
190 jonathan 629 propPanel = self.propPanel
191 jonathan 607
192 jonathan 877 if genSel in (GENCOMBOSTR_UNIFORM, \
193     GENCOMBOSTR_UNIQUE, \
194     GENCOMBOSTR_QUANTILES):
195    
196 jonathan 629 numGroups = genPanel.GetNumGroups()
197 jonathan 607
198 jonathan 635 index = self.propCombo.GetSelection()
199 jonathan 629
200 jonathan 635 propSel = self.propCombo.GetString(index)
201     propPanel = self.propCombo.GetClientData(index)
202 jonathan 629
203 jonathan 635 ramp = propPanel.GetRamp()
204 jonathan 629
205 jonathan 635 if genSel == GENCOMBOSTR_UNIFORM:
206 jonathan 629
207 jonathan 635 min = genPanel.GetMin()
208     max = genPanel.GetMax()
209 jonathan 629
210 jonathan 635 if min is not None \
211     and max is not None \
212     and numGroups is not None:
213 jonathan 629
214 jonathan 1100 self.clazz = GenUniformDistribution(
215 jonathan 635 min, max, numGroups, ramp,
216     self.type == FIELDTYPE_INT)
217 jonathan 629
218 jonathan 635 self.parent._SetClassification(self.clazz)
219 jonathan 629
220 jonathan 635 elif genSel == GENCOMBOSTR_UNIQUE:
221 jonathan 629
222 jonathan 635 list = genPanel.GetValueList()
223    
224     if len(list) > 0 \
225     and numGroups is not None:
226    
227 jonathan 1100 self.clazz = GenSingletonsFromList(
228 jonathan 635 list, numGroups, ramp)
229    
230     self.parent._SetClassification(self.clazz)
231    
232 jonathan 877 elif genSel == GENCOMBOSTR_QUANTILES:
233    
234     _range = genPanel.GetRange()
235     _list = genPanel.GetList()
236     _list.sort()
237    
238     delta = 1 / float(numGroups)
239     percents = [delta * i for i in range(1, numGroups + 1)]
240     adjusted, self.clazz = \
241 jonathan 1100 GenQuantiles(_list, percents, ramp, _range)
242 jonathan 877
243     if adjusted:
244     dlg = wxMessageDialog(self,
245     _("Based on the data from the table and the input\n" +
246     "values, the exact quantiles could not be generated.\n\n" +
247     "Accept a close estimate?"),
248     _("Problem with Quantiles"),
249    
250     wxYES_NO|wxYES_DEFAULT|wxICON_QUESTION)
251     if dlg.ShowModal() == wxID_YES:
252     self.parent._SetClassification(self.clazz)
253     else:
254     self.parent._SetClassification(self.clazz)
255    
256 jonathan 812 def OnCancel(self, event):
257 jonathan 629 self.Close()
258    
259     def _OnGenTypeSelect(self, event):
260 jonathan 877 self.__DoOnGenTypeSelect()
261     return
262 jonathan 629
263     combo = event.GetEventObject()
264    
265     selIndex = combo.GetSelection()
266    
267     if self.genPanel is not None:
268 jonathan 877 self.topBox.Show(self.genPanel, False)
269 jonathan 629
270     self.genPanel = combo.GetClientData(selIndex)
271     if self.genPanel is not None:
272 jonathan 877 self.topBox.Show(self.genPanel, True)
273 jonathan 629
274 jonathan 877 self.topBox.SetSizeHints(self)
275     self.topBox.Layout()
276 jonathan 629
277 jonathan 635 def _OnPropTypeSelect(self, event):
278     combo = event.GetEventObject()
279 jonathan 629
280 jonathan 635 selIndex = combo.GetSelection()
281     sel = combo.GetString(selIndex)
282    
283     if isinstance(self.propPanel, wxPanel):
284 jonathan 877 self.topBox.Show(self.propPanel, False)
285 jonathan 635
286     self.propPanel = combo.GetClientData(selIndex)
287    
288     if isinstance(self.propPanel, wxPanel):
289 jonathan 877 self.topBox.Show(self.propPanel, True)
290 jonathan 635
291 jonathan 877 self.topBox.SetSizeHints(self)
292     self.topBox.Layout()
293 jonathan 635
294 jonathan 877 def __DoOnGenTypeSelect(self):
295     choice = self.genChoice
296 jonathan 635
297 jonathan 877 sel = choice.GetSelection()
298     if sel == -1: return
299    
300     clazz, obj = choice.GetClientData(sel)
301    
302     if self.curGenPanel is not None:
303     self.curGenPanel.Hide()
304     self.sizer_genPanel.Remove(self.curGenPanel)
305    
306     self.curGenPanel = obj
307     self.curGenPanel.Show()
308    
309     self.sizer_genPanel.Add(self.curGenPanel, 1,
310     wxALL|wxEXPAND|wxADJUST_MINSIZE, 3)
311     self.sizer_genPanel.Layout()
312     self.Layout()
313     self.topBox.SetSizeHints(self)
314    
315 jonathan 629 ID_UNIFORM_MIN = 4001
316     ID_UNIFORM_MAX = 4002
317     ID_UNIFORM_NGROUPS = 4003
318     ID_UNIFORM_STEP = 4004
319     ID_UNIFORM_RETRIEVE = 4005
320    
321     class GenUniformPanel(wxPanel):
322    
323     def __init__(self, parent, layer, fieldName, fieldType):
324 jonathan 607 wxPanel.__init__(self, parent, -1)
325    
326     self.parent = parent
327 jonathan 629 self.layer = layer
328     self.fieldName = fieldName
329 jonathan 607 self.fieldType = fieldType
330    
331 jonathan 629 topSizer = wxStaticBoxSizer(wxStaticBox(self, -1, ""),
332 jonathan 607 wxVERTICAL)
333    
334 jonathan 629 #############
335    
336 jonathan 607 sizer = wxBoxSizer(wxHORIZONTAL)
337    
338     sizer.Add(wxStaticText(self, -1, _("Min:")), 0, wxALL, 4)
339 jonathan 629 self.minCtrl = wxTextCtrl(self, ID_UNIFORM_MIN, style=wxTE_RIGHT)
340     sizer.Add(self.minCtrl, 1, wxALL, 4)
341     EVT_TEXT(self, ID_UNIFORM_MIN, self._OnRangeChanged)
342 jonathan 607
343     sizer.Add(wxStaticText(self, -1, _("Max:")), 0, wxALL, 4)
344 jonathan 629 self.maxCtrl = wxTextCtrl(self, ID_UNIFORM_MAX, style=wxTE_RIGHT)
345     sizer.Add(self.maxCtrl, 1, wxALL, 4)
346     EVT_TEXT(self, ID_UNIFORM_MAX, self._OnRangeChanged)
347 jonathan 607
348 jonathan 629 sizer.Add(wxButton(self, ID_UNIFORM_RETRIEVE, _("Retrieve From Table")),
349     0, wxALL, 4)
350     EVT_BUTTON(self, ID_UNIFORM_RETRIEVE, self._OnRetrieve)
351    
352     topSizer.Add(sizer, 1, wxGROW, 0)
353    
354     #############
355    
356 jonathan 607 sizer = wxBoxSizer(wxHORIZONTAL)
357 jonathan 629
358 jonathan 607 sizer.Add(wxStaticText(self, -1, _("Number of Groups:")), 0, wxALL, 4)
359 jonathan 660 self.numGroupsCtrl = wxSpinCtrl(self, ID_UNIFORM_NGROUPS,
360     style=wxTE_RIGHT)
361 jonathan 629 EVT_TEXT(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)
362     EVT_SPINCTRL(self, ID_UNIFORM_NGROUPS, self._OnNumGroupsChanged)
363     sizer.Add(self.numGroupsCtrl, 1, wxALL, 4)
364 jonathan 607
365     sizer.Add(wxStaticText(self, -1, _("Stepping:")), 0, wxALL, 4)
366 jonathan 629 self.stepCtrl = wxTextCtrl(self, ID_UNIFORM_STEP, style=wxTE_RIGHT)
367     EVT_TEXT(self, ID_UNIFORM_STEP, self._OnSteppingChanged)
368     sizer.Add(self.stepCtrl , 1, wxALL, 4)
369 jonathan 607
370 jonathan 629 topSizer.Add(sizer, 1, wxGROW, 0)
371    
372     #############
373    
374 jonathan 607 self.SetSizer(topSizer)
375     self.SetAutoLayout(True)
376     topSizer.SetSizeHints(self)
377    
378     self.numGroupsChanging = False
379     self.steppingChanging = False
380    
381 jonathan 677 self.numGroupsCtrl.SetRange(1, sys.maxint)
382 jonathan 607
383     self.numGroupsCtrl.SetValue(1)
384     self.stepCtrl.SetValue("1")
385     self.maxCtrl.SetValue("0")
386     self.minCtrl.SetValue("0")
387     self.minCtrl.SetFocus()
388    
389     def GetNumGroups(self):
390     value = self.numGroupsCtrl.GetValue()
391     return self.__GetValidatedTypeEntry(self.numGroupsCtrl,
392     value,
393     FIELDTYPE_INT,
394     None)
395    
396     def GetStepping(self):
397     step = self.stepCtrl.GetValue()
398     return self.__GetValidatedTypeEntry(self.stepCtrl,
399     step,
400     self.fieldType,
401     0)
402    
403     def GetMin(self):
404     min = self.minCtrl.GetValue()
405     max = self.maxCtrl.GetValue()
406     return self.__GetValidatedTypeEntry(self.minCtrl,
407     min,
408     self.fieldType,
409     max)
410    
411     def GetMax(self):
412     min = self.minCtrl.GetValue()
413     max = self.maxCtrl.GetValue()
414     return self.__GetValidatedTypeEntry(self.maxCtrl,
415     max,
416     self.fieldType,
417     min)
418    
419     def _OnRangeChanged(self, event):
420    
421     hasFocus = wxWindow_FindFocus() == event.GetEventObject()
422     min = self.GetMin()
423     max = self.GetMax()
424    
425     on = min is not None \
426     and max is not None
427    
428     self.numGroupsCtrl.Enable(on)
429     self.stepCtrl.Enable(on)
430    
431     ngroups = self.GetNumGroups()
432    
433     if ngroups is not None \
434     and min is not None \
435     and max is not None \
436     and ngroups != 0:
437    
438 jonathan 629 #self.stepCtrl.SetValue(str((max - min) / ngroups))
439     self.stepCtrl.SetValue(str(self.__CalcStepping(min, max, ngroups)))
440     #self.numGroupsCtrl.SetValue(ngroups)
441 jonathan 607
442     self.parent.AllowGenerate(self.GetStepping() is not None)
443     else:
444     self.parent.AllowGenerate(False)
445    
446    
447     if hasFocus:
448     event.GetEventObject().SetFocus()
449    
450     def _OnNumGroupsChanged(self, event):
451     if self.steppingChanging:
452     self.steppingChanging = False
453     return
454    
455    
456     obj = event.GetEventObject()
457     ngroups = self.GetNumGroups()
458     min = self.GetMin()
459     max = self.GetMax()
460    
461     if ngroups is not None \
462     and min is not None \
463     and max is not None \
464     and ngroups != 0:
465    
466     #
467     # changing the value in the stepCtrl sends an event
468     # that the control is changing, at which point
469     # we try to update the numGroupsCtrl. This causes
470     # an infinite recursion. This flag and the one
471     # called steppingChanging tries to prevent the recursion.
472     #
473     self.numGroupsChanging = True
474    
475 jonathan 629 self.stepCtrl.SetValue(str(self.__CalcStepping(min, max, ngroups)))
476    
477 jonathan 607 self.parent.AllowGenerate(self.GetStepping() is not None)
478     else:
479     self.parent.AllowGenerate(False)
480    
481    
482     def _OnSteppingChanged(self, event):
483     if self.numGroupsChanging:
484     self.numGroupsChanging = False
485     return
486    
487     step = self.GetStepping()
488     min = self.GetMin()
489     max = self.GetMax()
490    
491     if step is not None \
492     and min is not None \
493     and max is not None \
494     and step != 0:
495    
496     #
497     # see note in _OnNumGroupsChanged
498     #
499     self.steppingChanging = True
500 jonathan 629 self.numGroupsCtrl.SetValue(self.__CalcNumGroups(min, max, step))
501 jonathan 607
502     self.parent.AllowGenerate(self.GetNumGroups() is not None)
503     else:
504     self.parent.AllowGenerate(False)
505    
506 jonathan 629 def _OnRetrieve(self, event):
507    
508     if self.layer.table is not None:
509 jonathan 812 wxBeginBusyCursor()
510 jonathan 1100 try:
511     min, max = self.layer.table.ValueRange(self.fieldName)
512     self.minCtrl.SetValue(str(min))
513     self.maxCtrl.SetValue(str(max))
514     finally:
515     wxEndBusyCursor()
516 jonathan 629
517 jonathan 607 def __GetValidatedTypeEntry(self, win, value, type, badValue = None):
518    
519     if type == FIELDTYPE_INT:
520     func = int
521     elif type == FIELDTYPE_DOUBLE:
522     func = float
523     elif type == FIELDTYPE_STRING:
524     func = str
525     else:
526     assert False, "Unsupported FIELDTYPE"
527     pass
528    
529     if self.__ValidateEntry(win, value, func, badValue):
530     return func(value)
531    
532     return None
533    
534     def __ValidateEntry(self, win, value, test, badValue = None):
535    
536     valid = value != ""
537    
538     try:
539     if valid:
540     value = test(value)
541    
542     if badValue is not None:
543     valid = value != test(badValue)
544     except ValueError:
545     valid = False
546    
547     if valid:
548     win.SetForegroundColour(wxBLACK)
549     else:
550     win.SetForegroundColour(wxRED)
551    
552 jonathan 620 win.Refresh()
553    
554 jonathan 607 return valid
555 jonathan 629
556     def __CalcStepping(self, min, max, ngroups):
557 jonathan 781 step = (max - min) / float(ngroups)
558 jonathan 629 if self.fieldType == FIELDTYPE_INT:
559     step = int(step)
560    
561     return step
562    
563     def __CalcNumGroups(self, min, max, step):
564     n = int((max - min) / step)
565     if n == 0:
566     n = 1
567    
568     if self.fieldType == FIELDTYPE_INT and step == 1:
569     n += 1
570    
571     return n
572    
573    
574     ID_UNIQUE_RETRIEVE = 4001
575     ID_UNIQUE_USEALL = 4002
576     ID_UNIQUE_USE = 4003
577     ID_UNIQUE_DONTUSE = 4004
578     ID_UNIQUE_USENONE = 4005
579     ID_UNIQUE_SORTAVAIL = 4006
580     ID_UNIQUE_SORTUSE = 4007
581 jonathan 649 ID_UNIQUE_REVAVAIL = 4008
582     ID_UNIQUE_REVUSE = 4009
583 jonathan 629
584     class GenUniquePanel(wxPanel):
585    
586     def __init__(self, parent, layer, fieldName, fieldType):
587     wxPanel.__init__(self, parent, -1)
588    
589     self.parent = parent
590     self.layer = layer
591     self.fieldName = fieldName
592     self.fieldType = fieldType
593    
594     topSizer = wxStaticBoxSizer(wxStaticBox(self, -1, ""),
595     wxVERTICAL)
596    
597    
598 jonathan 649 #bsizer = wxBoxSizer(wxVERTICAL)
599     topSizer.Add(wxButton(self, ID_UNIQUE_RETRIEVE,
600     _("Retrieve From Table")),
601     0, wxALL | wxALIGN_RIGHT, 4)
602    
603     EVT_BUTTON(self, ID_UNIQUE_RETRIEVE, self._OnRetrieve)
604    
605     #topSizer.Add(bsizer, 0, wxALL, 4)
606    
607 jonathan 629 sizer = wxBoxSizer(wxHORIZONTAL)
608    
609     self.dataList = []
610    
611     psizer = wxBoxSizer(wxVERTICAL)
612     self.list_avail = wxListCtrl(self, -1,
613     style=wxLC_REPORT | wxLC_SINGLE_SEL)
614     self.list_avail.InsertColumn(0, "Available")
615     self.list_avail_data = []
616     psizer.Add(self.list_avail, 1, wxGROW, 0)
617    
618 jonathan 649 bsizer = wxBoxSizer(wxHORIZONTAL)
619     bsizer.Add(wxButton(self, ID_UNIQUE_SORTAVAIL, _("Sort")))
620     EVT_BUTTON(self, ID_UNIQUE_SORTAVAIL, self._OnSortList)
621 jonathan 629
622 jonathan 649 bsizer.Add(wxButton(self, ID_UNIQUE_REVAVAIL, _("Reverse")))
623     EVT_BUTTON(self, ID_UNIQUE_REVAVAIL, self._OnReverseList)
624 jonathan 629
625 jonathan 649 psizer.Add(bsizer, 0, wxGROW, 0)
626 jonathan 629 sizer.Add(psizer, 1, wxGROW, 0)
627    
628 jonathan 607
629 jonathan 629 bsizer = wxBoxSizer(wxVERTICAL)
630 jonathan 649
631     bmp = resource.GetBitmapResource(USEALL_BMP, wxBITMAP_TYPE_XPM)
632     bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USEALL, bmp),
633 jonathan 629 0, wxGROW | wxALL, 4)
634 jonathan 649 bmp = resource.GetBitmapResource(USE_BMP, wxBITMAP_TYPE_XPM)
635     bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USE, bmp),
636 jonathan 629 0, wxGROW | wxALL, 4)
637 jonathan 649 bmp = resource.GetBitmapResource(USENOT_BMP, wxBITMAP_TYPE_XPM)
638     bsizer.Add(wxBitmapButton(self, ID_UNIQUE_DONTUSE, bmp),
639 jonathan 629 0, wxGROW | wxALL, 4)
640 jonathan 649 bmp = resource.GetBitmapResource(USENONE_BMP, wxBITMAP_TYPE_XPM)
641     bsizer.Add(wxBitmapButton(self, ID_UNIQUE_USENONE, bmp),
642 jonathan 629 0, wxGROW | wxALL, 4)
643 jonathan 607
644 jonathan 629 EVT_BUTTON(self, ID_UNIQUE_USEALL, self._OnUseAll)
645     EVT_BUTTON(self, ID_UNIQUE_USE, self._OnUse)
646     EVT_BUTTON(self, ID_UNIQUE_DONTUSE, self._OnDontUse)
647     EVT_BUTTON(self, ID_UNIQUE_USENONE, self._OnUseNone)
648 jonathan 607
649 jonathan 629 sizer.Add(bsizer, 0, wxALL | wxALIGN_CENTER_VERTICAL, 4)
650    
651     psizer = wxBoxSizer(wxVERTICAL)
652     self.list_use = wxListCtrl(self, -1,
653     style=wxLC_REPORT | wxLC_SINGLE_SEL)
654     self.list_use.InsertColumn(0, "Use")
655     self.list_use_data = []
656     psizer.Add(self.list_use, 1, wxGROW, 0)
657    
658 jonathan 649 bsizer = wxBoxSizer(wxHORIZONTAL)
659     bsizer.Add(wxButton(self, ID_UNIQUE_SORTUSE, _("Sort")))
660     EVT_BUTTON(self, ID_UNIQUE_SORTUSE, self._OnSortList)
661 jonathan 629
662 jonathan 649 bsizer.Add(wxButton(self, ID_UNIQUE_REVUSE, _("Reverse")))
663     EVT_BUTTON(self, ID_UNIQUE_REVUSE, self._OnReverseList)
664 jonathan 629
665 jonathan 649 psizer.Add(bsizer, 0, wxGROW, 0)
666    
667 jonathan 629 sizer.Add(psizer, 1, wxGROW, 0)
668    
669    
670     topSizer.Add(sizer, 1, wxGROW, 0)
671    
672     self.SetSizer(topSizer)
673     self.SetAutoLayout(True)
674     topSizer.SetSizeHints(self)
675    
676 frank 978 width, height = self.list_avail.GetSizeTuple()
677     self.list_avail.SetColumnWidth(0,width)
678     width, height = self.list_use.GetSizeTuple()
679     self.list_use.SetColumnWidth(0,width)
680    
681 jonathan 629 self.parent.AllowGenerate(False)
682    
683     def GetNumGroups(self):
684     return self.list_use.GetItemCount()
685    
686     def GetValueList(self):
687     list = []
688     for i in range(self.list_use.GetItemCount()):
689     list.append(self.dataList[self.list_use.GetItemData(i)])
690     return list
691    
692 jonathan 649 def _OnSortList(self, event):
693     id = event.GetId()
694 jonathan 629
695 jonathan 649 if id == ID_UNIQUE_SORTUSE:
696     list = self.list_use
697     else:
698     list = self.list_avail
699 jonathan 629
700 jonathan 649 list.SortItems(lambda i1, i2: cmp(self.dataList[i1],
701     self.dataList[i2]))
702    
703     def _OnReverseList(self, event):
704     id = event.GetId()
705    
706     if id == ID_UNIQUE_REVUSE:
707     list = self.list_use
708     else:
709     list = self.list_avail
710    
711     #
712     # always returning 1 reverses the list
713     #
714     list.SortItems(lambda i1, i2: 1)
715    
716 jonathan 629 def _OnRetrieve(self, event):
717     self.list_use.DeleteAllItems()
718     self.list_use_data = []
719     self.list_avail.DeleteAllItems()
720     self.list_avail_data = []
721    
722 bh 834 list = self.layer.table.UniqueValues(self.fieldName)
723 jonathan 629 index = 0
724     for v in list:
725     self.dataList.append(v)
726     i = self.list_avail.InsertStringItem(index, str(v))
727     self.list_avail.SetItemData(index, i)
728    
729     self.list_avail_data.append(v)
730     index += 1
731    
732     def _OnUseAll(self, event):
733     for i in range(self.list_avail.GetItemCount()):
734     self.__MoveListItem(0, self.list_avail, self.list_use)
735    
736     def _OnUse(self, event):
737     self.__MoveSelectedItems(self.list_avail, self.list_use)
738    
739     def _OnDontUse(self, event):
740     self.__MoveSelectedItems(self.list_use, self.list_avail)
741    
742     def _OnUseNone(self, event):
743    
744     for i in range(self.list_use.GetItemCount()):
745     self.__MoveListItem(0, self.list_use, self.list_avail)
746    
747     def __MoveSelectedItems(self, list_src, list_dest):
748     while True:
749     index = list_src.GetNextItem(-1,
750     wxLIST_NEXT_ALL,
751     wxLIST_STATE_SELECTED)
752    
753     if index == -1:
754     break
755    
756     self.__MoveListItem(index, list_src, list_dest)
757    
758    
759     def __MoveListItem(self, index, list_src, list_dest):
760    
761     item = list_src.GetItem(index)
762    
763     x = list_dest.InsertStringItem(
764     list_dest.GetItemCount(),
765     str(self.dataList[item.GetData()]))
766    
767     list_dest.SetItemData(x, item.GetData())
768    
769     list_src.DeleteItem(index)
770    
771     # def _OnListSize(self, event):
772     # list = event.GetEventObject()
773    
774     # list.SetColumnWidth(0, event.GetSize().GetWidth())
775     #
776    
777 jonathan 877 ID_QUANTILES_RANGE = 4001
778     ID_QUANTILES_RETRIEVE = 4002
779    
780     class GenQuantilesPanel(wxPanel):
781    
782     def __init__(self, parent, layer, fieldName, fieldType):
783     wxPanel.__init__(self, parent, -1)
784    
785     self.parent = parent
786     self.layer = layer
787     self.fieldName = fieldName
788     self.fieldType = fieldType
789    
790     topBox = wxStaticBoxSizer(wxStaticBox(self, -1, ""),
791     wxVERTICAL)
792    
793     self.text_range = wxTextCtrl(self, ID_QUANTILES_RANGE, "")
794     self.button_retrieve = wxButton(self, ID_QUANTILES_RETRIEVE,
795     _("Retrieve from Table"))
796    
797     self.spin_numClasses = wxSpinCtrl(self, -1, style=wxTE_RIGHT)
798     self.spin_numClasses.SetRange(1, sys.maxint)
799     self.spin_numClasses.SetValue(1)
800    
801    
802     sizer = wxBoxSizer(wxHORIZONTAL)
803     sizer.Add(wxStaticText(self, -1, _("Apply to Range")), 0, wxALL, 4)
804     sizer.Add(self.text_range, 1, wxALL, 4)
805     sizer.Add(self.button_retrieve, 0, wxALL, 4)
806    
807     topBox.Add(sizer, 0, wxEXPAND, 0)
808    
809     sizer = wxBoxSizer(wxHORIZONTAL)
810     sizer.Add(wxStaticText(self, -1, _("Number of Classes:")), 0, wxALL, 4)
811     sizer.Add(self.spin_numClasses, 1, wxALL, 4)
812    
813     topBox.Add(sizer, 0, wxEXPAND, 0)
814    
815     self.SetSizer(topBox)
816     self.SetAutoLayout(True)
817     topBox.Fit(self)
818     topBox.SetSizeHints(self)
819    
820     EVT_TEXT(self, ID_QUANTILES_RANGE, self.OnRangeText)
821     EVT_BUTTON(self, ID_QUANTILES_RETRIEVE, self.OnRetrieve)
822    
823     self.__range = None
824    
825     def GetNumGroups(self):
826     return self.spin_numClasses.GetValue()
827    
828     def GetRange(self):
829     assert self.__range is not None
830    
831     return self.__range
832    
833     def GetList(self):
834    
835 jonathan 898 _list = []
836    
837 jonathan 877 if self.layer.table is not None:
838 bh 1122 wxBeginBusyCursor()
839 jonathan 1100 try:
840     #
841     # FIXME: Replace with a call to table when the method
842     # has been written to get all the values
843     #
844     table = self.layer.table
845     for i in range(table.NumRows()):
846     _list.append(table.ReadValue(i, self.fieldName))
847     finally:
848     wxEndBusyCursor()
849 jonathan 898
850     return _list
851 jonathan 877
852     def OnRangeText(self, event):
853    
854     try:
855     self.__range = Range(self.text_range.GetValue())
856     except ValueError:
857     self.__range = None
858    
859     if self.__range is not None:
860     self.text_range.SetForegroundColour(wxBLACK)
861     else:
862     self.text_range.SetForegroundColour(wxRED)
863    
864     def OnRetrieve(self, event):
865    
866     if self.layer.table is not None:
867     wxBeginBusyCursor()
868 jonathan 1100 try:
869     min, max = self.layer.table.ValueRange(self.fieldName)
870     self.text_range.SetValue("[" + str(min) + ";" + str(max) + "]")
871     finally:
872     wxEndBusyCursor()
873 jonathan 877
874 jonathan 629 ID_CUSTOMRAMP_COPYSTART = 4001
875     ID_CUSTOMRAMP_COPYEND = 4002
876     ID_CUSTOMRAMP_EDITSTART = 4003
877     ID_CUSTOMRAMP_EDITEND = 4004
878     ID_CUSTOMRAMP_SPROP = 4005
879     ID_CUSTOMRAMP_EPROP = 4006
880    
881     class CustomRampPanel(wxPanel):
882    
883     def __init__(self, parent, shapeType):
884 jonathan 607 wxPanel.__init__(self, parent, -1)
885    
886 jonathan 629 topSizer = wxStaticBoxSizer(wxStaticBox(self, -1, ""), wxHORIZONTAL)
887 jonathan 607
888 jonathan 629 bsizer = wxBoxSizer(wxVERTICAL)
889     bsizer.Add(wxStaticText(self, -1, _("Start:")), 0, wxALL | wxCENTER, 4)
890     self.startPropCtrl = classifier.ClassGroupPropertiesCtrl(
891     self, ID_CUSTOMRAMP_SPROP,
892     ClassGroupProperties(), shapeType,
893     style=wxSIMPLE_BORDER, size=(40, 20))
894     bsizer.Add(self.startPropCtrl, 1, wxGROW | wxALL | wxCENTER, 4)
895     bsizer.Add(wxButton(self, ID_CUSTOMRAMP_EDITSTART, _("Change")),
896     0, wxGROW | wxALL | wxCENTER, 4)
897    
898     topSizer.Add(bsizer,
899     1, wxALL \
900     | wxSHAPED \
901     | wxALIGN_CENTER_HORIZONTAL \
902     | wxALIGN_CENTER_VERTICAL, \
903     4)
904    
905 jonathan 649 bmp = resource.GetBitmapResource(USE_BMP, wxBITMAP_TYPE_XPM)
906 jonathan 629 bsizer = wxBoxSizer(wxVERTICAL)
907 jonathan 649 bsizer.Add(wxBitmapButton(self, ID_CUSTOMRAMP_COPYSTART, bmp),
908 jonathan 629 0, wxGROW | wxALL, 4)
909 jonathan 649 bmp = resource.GetBitmapResource(USENOT_BMP, wxBITMAP_TYPE_XPM)
910     bsizer.Add(wxBitmapButton(self, ID_CUSTOMRAMP_COPYEND, bmp),
911 jonathan 629 0, wxGROW | wxALL, 4)
912    
913     topSizer.Add(bsizer,
914     0, wxALL \
915     | wxALIGN_CENTER_HORIZONTAL \
916     | wxALIGN_CENTER_VERTICAL,
917     4)
918    
919     bsizer = wxBoxSizer(wxVERTICAL)
920     bsizer.Add(wxStaticText(self, -1, _("End:")), 0, wxALL | wxCENTER, 4)
921     self.endPropCtrl = classifier.ClassGroupPropertiesCtrl(
922     self, ID_CUSTOMRAMP_EPROP,
923     ClassGroupProperties(), shapeType,
924     style=wxSIMPLE_BORDER, size=(40, 20))
925     bsizer.Add(self.endPropCtrl, 1, wxGROW | wxALL | wxCENTER, 4)
926     bsizer.Add(wxButton(self, ID_CUSTOMRAMP_EDITEND, _("Change")),
927     0, wxGROW | wxALL | wxCENTER, 4)
928    
929     topSizer.Add(bsizer,
930     1, wxALL \
931     | wxSHAPED \
932     | wxALIGN_RIGHT \
933     | wxALIGN_CENTER_HORIZONTAL \
934     | wxALIGN_CENTER_VERTICAL,
935     4)
936    
937     EVT_BUTTON(self, ID_CUSTOMRAMP_COPYSTART, self._OnCopyStart)
938     EVT_BUTTON(self, ID_CUSTOMRAMP_COPYEND, self._OnCopyEnd)
939     EVT_BUTTON(self, ID_CUSTOMRAMP_EDITSTART, self._OnEditStart)
940     EVT_BUTTON(self, ID_CUSTOMRAMP_EDITEND, self._OnEditEnd)
941    
942     self.SetSizer(topSizer)
943     self.SetAutoLayout(True)
944     topSizer.SetSizeHints(self)
945    
946 jonathan 635 def GetRamp(self):
947     return CustomRamp(self.startPropCtrl.GetProperties(),
948     self.endPropCtrl.GetProperties())
949 jonathan 629
950     def _OnCopyStart(self, event):
951     self.endPropCtrl.SetProperties(self.startPropCtrl.GetProperties())
952    
953     def _OnCopyEnd(self, event):
954     self.startPropCtrl.SetProperties(self.endPropCtrl.GetProperties())
955    
956     def _OnEditStart(self, event):
957     self.startPropCtrl.DoEdit()
958    
959     def _OnEditEnd(self, event):
960     self.endPropCtrl.DoEdit()
961    
962 jonathan 877

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26