/[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 907 - (hide annotations)
Fri May 16 15:01:04 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: 30103 byte(s)
* Thuban/Model/table.py (Table): Remove this compatibility alias
for DBFTable.

* test/test_table.py: Import DBFTable as Table because that alias
doesn't exist anymore.

* Thuban/UI/classgen.py: Remove some unused imports

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