/[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 898 - (hide annotations)
Mon May 12 12:19:58 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: 30207 byte(s)
(GenQuantilesPanel.GetList): Replace call
        to table.UniqueValues() with calls that retrieve all the values
        from the table. This will need to be replaced by a method on table
        which can simply return the list (perhaps more efficiently).

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