/[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 1100 - (hide annotations)
Fri May 30 06:28:21 2003 UTC (21 years, 9 months ago) by jonathan
Original Path: trunk/thuban/Thuban/UI/classgen.py
File MIME type: text/x-python
File size: 30680 byte(s)
Use classgen functions that were part
        of the ClassGenerator class. Put try/finally blocks around
        code that uses wxBeginBusyCursor()/wxEndBusyCursor(). Fixes
        RTBug #1904.

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 jonathan 1100 try:
839     wxBeginBusyCursor()
840 jonathan 898
841 jonathan 1100 #
842     # FIXME: Replace with a call to table when the method
843     # has been written to get all the values
844     #
845     table = self.layer.table
846     for i in range(table.NumRows()):
847     _list.append(table.ReadValue(i, self.fieldName))
848     finally:
849     wxEndBusyCursor()
850 jonathan 898
851     return _list
852 jonathan 877
853     def OnRangeText(self, event):
854    
855     try:
856     self.__range = Range(self.text_range.GetValue())
857     except ValueError:
858     self.__range = None
859    
860     if self.__range is not None:
861     self.text_range.SetForegroundColour(wxBLACK)
862     else:
863     self.text_range.SetForegroundColour(wxRED)
864    
865     def OnRetrieve(self, event):
866    
867     if self.layer.table is not None:
868     wxBeginBusyCursor()
869 jonathan 1100 try:
870     min, max = self.layer.table.ValueRange(self.fieldName)
871     self.text_range.SetValue("[" + str(min) + ";" + str(max) + "]")
872     finally:
873     wxEndBusyCursor()
874 jonathan 877
875 jonathan 629 ID_CUSTOMRAMP_COPYSTART = 4001
876     ID_CUSTOMRAMP_COPYEND = 4002
877     ID_CUSTOMRAMP_EDITSTART = 4003
878     ID_CUSTOMRAMP_EDITEND = 4004
879     ID_CUSTOMRAMP_SPROP = 4005
880     ID_CUSTOMRAMP_EPROP = 4006
881    
882     class CustomRampPanel(wxPanel):
883    
884     def __init__(self, parent, shapeType):
885 jonathan 607 wxPanel.__init__(self, parent, -1)
886    
887 jonathan 629 topSizer = wxStaticBoxSizer(wxStaticBox(self, -1, ""), wxHORIZONTAL)
888 jonathan 607
889 jonathan 629 bsizer = wxBoxSizer(wxVERTICAL)
890     bsizer.Add(wxStaticText(self, -1, _("Start:")), 0, wxALL | wxCENTER, 4)
891     self.startPropCtrl = classifier.ClassGroupPropertiesCtrl(
892     self, ID_CUSTOMRAMP_SPROP,
893     ClassGroupProperties(), shapeType,
894     style=wxSIMPLE_BORDER, size=(40, 20))
895     bsizer.Add(self.startPropCtrl, 1, wxGROW | wxALL | wxCENTER, 4)
896     bsizer.Add(wxButton(self, ID_CUSTOMRAMP_EDITSTART, _("Change")),
897     0, wxGROW | wxALL | wxCENTER, 4)
898    
899     topSizer.Add(bsizer,
900     1, wxALL \
901     | wxSHAPED \
902     | wxALIGN_CENTER_HORIZONTAL \
903     | wxALIGN_CENTER_VERTICAL, \
904     4)
905    
906 jonathan 649 bmp = resource.GetBitmapResource(USE_BMP, wxBITMAP_TYPE_XPM)
907 jonathan 629 bsizer = wxBoxSizer(wxVERTICAL)
908 jonathan 649 bsizer.Add(wxBitmapButton(self, ID_CUSTOMRAMP_COPYSTART, bmp),
909 jonathan 629 0, wxGROW | wxALL, 4)
910 jonathan 649 bmp = resource.GetBitmapResource(USENOT_BMP, wxBITMAP_TYPE_XPM)
911     bsizer.Add(wxBitmapButton(self, ID_CUSTOMRAMP_COPYEND, bmp),
912 jonathan 629 0, wxGROW | wxALL, 4)
913    
914     topSizer.Add(bsizer,
915     0, wxALL \
916     | wxALIGN_CENTER_HORIZONTAL \
917     | wxALIGN_CENTER_VERTICAL,
918     4)
919    
920     bsizer = wxBoxSizer(wxVERTICAL)
921     bsizer.Add(wxStaticText(self, -1, _("End:")), 0, wxALL | wxCENTER, 4)
922     self.endPropCtrl = classifier.ClassGroupPropertiesCtrl(
923     self, ID_CUSTOMRAMP_EPROP,
924     ClassGroupProperties(), shapeType,
925     style=wxSIMPLE_BORDER, size=(40, 20))
926     bsizer.Add(self.endPropCtrl, 1, wxGROW | wxALL | wxCENTER, 4)
927     bsizer.Add(wxButton(self, ID_CUSTOMRAMP_EDITEND, _("Change")),
928     0, wxGROW | wxALL | wxCENTER, 4)
929    
930     topSizer.Add(bsizer,
931     1, wxALL \
932     | wxSHAPED \
933     | wxALIGN_RIGHT \
934     | wxALIGN_CENTER_HORIZONTAL \
935     | wxALIGN_CENTER_VERTICAL,
936     4)
937    
938     EVT_BUTTON(self, ID_CUSTOMRAMP_COPYSTART, self._OnCopyStart)
939     EVT_BUTTON(self, ID_CUSTOMRAMP_COPYEND, self._OnCopyEnd)
940     EVT_BUTTON(self, ID_CUSTOMRAMP_EDITSTART, self._OnEditStart)
941     EVT_BUTTON(self, ID_CUSTOMRAMP_EDITEND, self._OnEditEnd)
942    
943     self.SetSizer(topSizer)
944     self.SetAutoLayout(True)
945     topSizer.SetSizeHints(self)
946    
947 jonathan 635 def GetRamp(self):
948     return CustomRamp(self.startPropCtrl.GetProperties(),
949     self.endPropCtrl.GetProperties())
950 jonathan 629
951     def _OnCopyStart(self, event):
952     self.endPropCtrl.SetProperties(self.startPropCtrl.GetProperties())
953    
954     def _OnCopyEnd(self, event):
955     self.startPropCtrl.SetProperties(self.endPropCtrl.GetProperties())
956    
957     def _OnEditStart(self, event):
958     self.startPropCtrl.DoEdit()
959    
960     def _OnEditEnd(self, event):
961     self.endPropCtrl.DoEdit()
962    
963 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