/[thuban]/trunk/thuban/Thuban/UI/classifier.py
ViewVC logotype

Diff of /trunk/thuban/Thuban/UI/classifier.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 460 by jonathan, Wed Mar 5 18:16:28 2003 UTC revision 507 by jonathan, Mon Mar 10 17:36:42 2003 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001 by Intevation GmbH  # Copyright (c) 2001, 2003 by Intevation GmbH
2  # Authors:  # Authors:
3  # Jonathan Coles <[email protected]>  # Jonathan Coles <[email protected]>
4  #  #
# Line 11  __version__ = "$Revision$" Line 11  __version__ = "$Revision$"
11    
12  import copy  import copy
13    
14    from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_DOUBLE, \
15         FIELDTYPE_STRING
16    
17  from wxPython.wx import *  from wxPython.wx import *
18  from wxPython.grid import *  from wxPython.grid import *
19    
# Line 24  from Thuban.Model.color import Color Line 27  from Thuban.Model.color import Color
27    
28  from Thuban.Model.layer import Layer, SHAPETYPE_ARC, SHAPETYPE_POLYGON, SHAPETYPE_POINT  from Thuban.Model.layer import Layer, SHAPETYPE_ARC, SHAPETYPE_POLYGON, SHAPETYPE_POINT
29    
30    from dialogs import NonModalDialog
31    
32  # widget id's  # widget id's
33  ID_PROPERTY_SELECT = 4010  ID_PROPERTY_SELECT = 4010
34  ID_CLASS_TABLE = 40011  ID_CLASS_TABLE = 40011
# Line 35  ID_CLASSIFY_GENRANGE = 4004 Line 40  ID_CLASSIFY_GENRANGE = 4004
40  ID_CLASSIFY_REMOVE = 4005  ID_CLASSIFY_REMOVE = 4005
41  ID_CLASSIFY_MOVEUP = 4006  ID_CLASSIFY_MOVEUP = 4006
42  ID_CLASSIFY_MOVEDOWN = 4007  ID_CLASSIFY_MOVEDOWN = 4007
43    ID_CLASSIFY_APPLY = 4008
44    
45  # table columns  # table columns
46  COL_SYMBOL = 0  COL_SYMBOL = 0
# Line 62  class ClassGrid(wxGrid): Line 68  class ClassGrid(wxGrid):
68                   use for display.                   use for display.
69          """          """
70    
71          wxGrid.__init__(self, parent, ID_CLASS_TABLE, size = (340, 160))          #wxGrid.__init__(self, parent, ID_CLASS_TABLE, size = (340, 160))
72          self.SetTable(ClassTable(fieldData, layer.ShapeType(), self), true)          wxGrid.__init__(self, parent, ID_CLASS_TABLE)
73          self.SetSelectionMode(wxGrid.wxGridSelectRows)          #self.SetTable(ClassTable(fieldData, layer.ShapeType(), self), true)
74    
75          EVT_GRID_CELL_LEFT_DCLICK(self, self._OnCellDClick)          EVT_GRID_CELL_LEFT_DCLICK(self, self._OnCellDClick)
76          EVT_GRID_RANGE_SELECT(self, self._OnSelectedRange)          EVT_GRID_RANGE_SELECT(self, self._OnSelectedRange)
# Line 79  class ClassGrid(wxGrid): Line 85  class ClassGrid(wxGrid):
85          self.shapeType = shapeType          self.shapeType = shapeType
86          table = self.GetTable()          table = self.GetTable()
87          if table is None:          if table is None:
88                w = self.GetDefaultColSize() * 3 + self.GetDefaultRowLabelSize()
89                h = self.GetDefaultRowSize() * 4 + self.GetDefaultColLabelSize()
90                self.SetDimensions(-1, -1, w, h)
91                self.SetSizeHints(w, h, -1, -1)
92              self.SetTable(ClassTable(clazz, self.shapeType, self), true)              self.SetTable(ClassTable(clazz, self.shapeType, self), true)
93          else:          else:
94              table.Reset(clazz, self.shapeType)              table.Reset(clazz, self.shapeType)
95    
96            self.SetSelectionMode(wxGrid.wxGridSelectRows)
97          self.ClearSelection()          self.ClearSelection()
98    
99      def GetCurrentSelection(self):      def GetCurrentSelection(self):
# Line 125  class ClassGrid(wxGrid): Line 136  class ClassGrid(wxGrid):
136          # if only one thing is selected check if it is the default          # if only one thing is selected check if it is the default
137          # data row, because we can't remove that          # data row, because we can't remove that
138          if len(sel) == 1:          if len(sel) == 1:
139              group = self.GetTable().GetValueAsCustom(sel[0], COL_SYMBOL, None)              #group = self.GetTable().GetValueAsCustom(sel[0], COL_SYMBOL, None)
140                group = self.GetTable().GetClassGroup(sel[0])
141              if isinstance(group, ClassGroupDefault):              if isinstance(group, ClassGroupDefault):
142                  wxMessageDialog(self,                  wxMessageDialog(self,
143                                  "The Default group cannot be removed.",                                  "The Default group cannot be removed.",
# Line 174  class ClassGrid(wxGrid): Line 186  class ClassGrid(wxGrid):
186          r = event.GetRow()          r = event.GetRow()
187          c = event.GetCol()          c = event.GetCol()
188          if c == COL_SYMBOL:          if c == COL_SYMBOL:
189              group = self.GetTable().GetValueAsCustom(r, c, None)              prop = self.GetTable().GetValueAsCustom(r, c, None)
190              prop = group.GetProperties()              #prop = group.GetProperties()
191    
192              # get a new ClassGroupProperties object and copy the              # get a new ClassGroupProperties object and copy the
193              # values over to our current object              # values over to our current object
194              propDlg = SelectPropertiesDialog(NULL, prop, self.shapeType)              propDlg = SelectPropertiesDialog(NULL, prop, self.shapeType)
195              if propDlg.ShowModal() == wxID_OK:              if propDlg.ShowModal() == wxID_OK:
196                  new_prop = propDlg.GetClassGroupProperties()                  new_prop = propDlg.GetClassGroupProperties()
197                  prop.SetProperties(new_prop)                  #prop.SetProperties(new_prop)
198                  self.Refresh()                  self.GetTable().SetValueAsCustom(r, c, None, new_prop)
199              propDlg.Destroy()              propDlg.Destroy()
200    
201      #      #
# Line 227  class ClassTable(wxPyGridTableBase): Line 239  class ClassTable(wxPyGridTableBase):
239          """          """
240    
241          wxPyGridTableBase.__init__(self)          wxPyGridTableBase.__init__(self)
242    
243          self.SetView(view)          self.SetView(view)
244          self.tdata = []          self.tdata = []
245    
# Line 250  class ClassTable(wxPyGridTableBase): Line 263  class ClassTable(wxPyGridTableBase):
263    
264          self.GetView().BeginBatch()          self.GetView().BeginBatch()
265    
266          self.clazz = clazz          self.fieldType = clazz.GetFieldType()
267          self.shapeType = shapeType          self.shapeType = shapeType
         self.renderer = ClassRenderer(self.shapeType)  
268    
269          old_len = len(self.tdata)          old_len = len(self.tdata)
270    
# Line 262  class ClassTable(wxPyGridTableBase): Line 274  class ClassTable(wxPyGridTableBase):
274          # copy the data out of the classification and into our          # copy the data out of the classification and into our
275          # array          # array
276          #          #
277          for p in self.clazz:          for p in clazz:
278              np = copy.copy(p)              np = copy.deepcopy(p)
279              self.__SetRow(-1, np)              self.__SetRow(-1, np)
280    
281    
282          self.__Modified(False)          self.__Modified(-1)
283    
284          self.__NotifyRowChanges(old_len, len(self.tdata))          self.__NotifyRowChanges(old_len, len(self.tdata))
285    
286                
287          self.GetView().EndBatch()          self.GetView().EndBatch()
288    
289      def __NotifyRowChanges(self, curRows, newRows):      def __NotifyRowChanges(self, curRows, newRows):
# Line 292  class ClassTable(wxPyGridTableBase): Line 306  class ClassTable(wxPyGridTableBase):
306      def __SetRow(self, row, group):      def __SetRow(self, row, group):
307          """Set a row's data to that of the group.          """Set a row's data to that of the group.
308    
309            The table is considered modified after this operation.
310    
311          row -- if row is -1 or greater than the current number of rows          row -- if row is -1 or greater than the current number of rows
312                 then group is appended to the end.                 then group is appended to the end.
313          """          """
# Line 356  class ClassTable(wxPyGridTableBase): Line 372  class ClassTable(wxPyGridTableBase):
372          group = self.tdata[row]          group = self.tdata[row]
373    
374          if col == COL_SYMBOL:          if col == COL_SYMBOL:
375              return group              return group.GetProperties()
376    
377          if col == COL_LABEL:          if col == COL_LABEL:
378              return group.GetLabel()              return group.GetLabel()
# Line 382  class ClassTable(wxPyGridTableBase): Line 398  class ClassTable(wxPyGridTableBase):
398          value, or of length two if it is a range.          value, or of length two if it is a range.
399          """          """
400    
401          type = self.clazz.GetFieldType()          type = self.fieldType
402    
403          if type == FIELDTYPE_STRING:          if type == FIELDTYPE_STRING:
404              return (value,)              return (value,)
# Line 412  class ClassTable(wxPyGridTableBase): Line 428  class ClassTable(wxPyGridTableBase):
428                  return (conv(Str2Num(value[:i])), conv(Str2Num(value[i+1:])))                  return (conv(Str2Num(value[:i])), conv(Str2Num(value[i+1:])))
429    
430          assert(False) # shouldn't get here          assert(False) # shouldn't get here
431            return (0,)
432                            
433    
434      def SetValueAsCustom(self, row, col, typeName, value):      def SetValueAsCustom(self, row, col, typeName, value):
# Line 431  class ClassTable(wxPyGridTableBase): Line 448  class ClassTable(wxPyGridTableBase):
448    
449          group = self.tdata[row]          group = self.tdata[row]
450    
451          mod = False          mod = True # assume the data will change
452    
453          if col == COL_SYMBOL:          if col == COL_SYMBOL:
454              self.__SetRow(row, value)              group.SetProperties(value)
455              mod = True          elif col == COL_LABEL:
456                group.SetLabel(value)
457          elif col == COL_VALUE:          elif col == COL_VALUE:
458              if isinstance(group, ClassGroupDefault):              if isinstance(group, ClassGroupDefault):
459                  # not allowed to modify the default value                  # not allowed to modify the default value
# Line 448  class ClassTable(wxPyGridTableBase): Line 466  class ClassTable(wxPyGridTableBase):
466                      dataInfo = self.__ParseInput(value)                      dataInfo = self.__ParseInput(value)
467                  except ValueError:                  except ValueError:
468                      # bad input, ignore the request                      # bad input, ignore the request
469                      pass                      mod = False
470                  else:                  else:
471    
472                        changed = False
473                      ngroup = group                      ngroup = group
474                      props = group.GetProperties()                      props = group.GetProperties()
475    
# Line 462  class ClassTable(wxPyGridTableBase): Line 481  class ClassTable(wxPyGridTableBase):
481                      if len(dataInfo) == 1:                      if len(dataInfo) == 1:
482                          if not isinstance(group, ClassGroupSingleton):                          if not isinstance(group, ClassGroupSingleton):
483                              ngroup = ClassGroupSingleton(prop = props)                              ngroup = ClassGroupSingleton(prop = props)
484                                changed = True
485                          ngroup.SetValue(dataInfo[0])                          ngroup.SetValue(dataInfo[0])
486                      elif len(dataInfo) == 2:                      elif len(dataInfo) == 2:
487                          if not isinstance(group, ClassGroupRange):                          if not isinstance(group, ClassGroupRange):
488                              ngroup = ClassGroupRange(prop = props)                              ngroup = ClassGroupRange(prop = props)
489                                changed = True
490                          ngroup.SetRange(dataInfo[0], dataInfo[1])                          ngroup.SetRange(dataInfo[0], dataInfo[1])
491                      else:                      else:
492                          assert(False)                          assert(False)
493                            pass
494    
495                      ngroup.SetLabel(group.GetLabel())                      if changed:
496                            ngroup.SetLabel(group.GetLabel())
497                      self.__SetRow(row, ngroup)                          self.SetClassGroup(row, ngroup)
498            else:
499                      mod = True              assert(False) # shouldn't be here
500                pass
   
         elif col == COL_LABEL:  
             group.SetLabel(value)  
             mod = True  
501    
502          if mod:          if mod:
503              self.__Modified()              self.__Modified()
504              self.GetView().Refresh()              self.GetView().Refresh()
505    
# Line 492  class ClassTable(wxPyGridTableBase): Line 510  class ClassTable(wxPyGridTableBase):
510          #attr = wxPyGridTableBase.GetAttr(self, row, col, someExtraParameter)          #attr = wxPyGridTableBase.GetAttr(self, row, col, someExtraParameter)
511    
512          if col == COL_SYMBOL:          if col == COL_SYMBOL:
513                # we need to create a new renderer each time, because
514                # SetRenderer takes control of the parameter
515              attr.SetRenderer(ClassRenderer(self.shapeType))              attr.SetRenderer(ClassRenderer(self.shapeType))
516              attr.SetReadOnly()              attr.SetReadOnly()
517    
# Line 500  class ClassTable(wxPyGridTableBase): Line 520  class ClassTable(wxPyGridTableBase):
520      def GetClassGroup(self, row):      def GetClassGroup(self, row):
521          """Return the ClassGroup object representing row 'row'."""          """Return the ClassGroup object representing row 'row'."""
522    
523          return self.GetValueAsCustom(row, COL_SYMBOL, None)          return self.tdata[row] # self.GetValueAsCustom(row, COL_SYMBOL, None)
524    
525      def SetClassGroup(self, row, group):      def SetClassGroup(self, row, group):
526          self.SetValueAsCustom(row, COL_SYMBOL, None, group)          self.__SetRow(row, group)
527            self.GetView().Refresh()
528    
529      def __Modified(self, mod = True):      def __Modified(self, mod = True):
530          """Set the modified flag."""          """Adjust the modified flag.
531          self.modified = mod  
532            mod -- if -1 set the modified flag to False, otherwise perform
533                   an 'or' operation with the current value of the flag and
534                   'mod'
535            """
536    
537            if mod == -1:
538                self.modified = False
539            else:
540                self.modified = mod or self.modified
541    
542      def IsModified(self):      def IsModified(self):
543          """True if this table is considered modified."""          """True if this table is considered modified."""
544          return self.modified          return self.modified
545    
546      def DeleteRows(self, pos, numRows = 1):      def DeleteRows(self, pos, numRows = 1):
547          """Deletes 'numRows' beginning at row 'pos'.          """Deletes 'numRows' beginning at row 'pos'.
548    
549          The table is considered modified after this operation.          The row representing the default group is not removed.
550    
551            The table is considered modified if any rows are removed.
552          """          """
553    
554          assert(pos >= 0)          assert(pos >= 0)
555          old_len = len(self.tdata)          old_len = len(self.tdata)
556          for row in range(pos, pos - numRows, -1):          for row in range(pos, pos - numRows, -1):
557              group = self.GetValueAsCustom(row, COL_SYMBOL, None)              group = self.GetClassGroup(row)
558              if not isinstance(group, ClassGroupDefault):              if not isinstance(group, ClassGroupDefault):
559                  self.tdata.pop(row)                  self.tdata.pop(row)
560                  self.__Modified()                  self.__Modified()
# Line 531  class ClassTable(wxPyGridTableBase): Line 563  class ClassTable(wxPyGridTableBase):
563              self.__NotifyRowChanges(old_len, len(self.tdata))              self.__NotifyRowChanges(old_len, len(self.tdata))
564    
565      def AppendRows(self, numRows = 1):      def AppendRows(self, numRows = 1):
566          """Append 'numRows' empty rows to the end of the table."""          """Append 'numRows' empty rows to the end of the table.
567    
568            The table is considered modified if any rows are appended.
569            """
570    
571          old_len = len(self.tdata)          old_len = len(self.tdata)
572          for i in range(numRows):          for i in range(numRows):
573              np = ClassGroupSingleton()              np = ClassGroupSingleton()
574              self.__SetRow(-1, np)              self.__SetRow(-1, np)
             #self.tdata.append([np, np.GetValue(), np.GetLabel()])  
             self.__Modified()  
575    
576          if self.IsModified():          if self.IsModified():
577              self.__NotifyRowChanges(old_len, len(self.tdata))              self.__NotifyRowChanges(old_len, len(self.tdata))
578    
579    
580  class Classifier(wxDialog):  class Classifier(NonModalDialog):
581            
582      def __init__(self, parent, layer):      def __init__(self, parent, interactor, name, layer):
583          wxDialog.__init__(self, parent, -1, _("Classify"),          NonModalDialog.__init__(self, parent, interactor, name,
584                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)                                  _("Classifier: %s") % layer.Title())
   
585    
586          self.layer = layer          self.layer = layer
587    
588            self.originalClass = self.layer.GetClassification()
589            field = self.originalClass.GetField()
590            fieldType = self.originalClass.GetFieldType()
591    
592          topBox = wxBoxSizer(wxVERTICAL)          topBox = wxBoxSizer(wxVERTICAL)
593    
594          topBox.Add(wxStaticText(self, -1, _("Layer: %s") % layer.Title()),          #topBox.Add(wxStaticText(self, -1, _("Layer: %s") % layer.Title()),
595              0, wxALIGN_LEFT | wxALL, 4)              #0, wxALIGN_LEFT | wxALL, 4)
596          topBox.Add(wxStaticText(self, -1, _("Type: %s") % layer.ShapeType()),          topBox.Add(wxStaticText(self, -1,
597                                    _("Layer Type: %s") % layer.ShapeType()),
598              0, wxALIGN_LEFT | wxALL, 4)              0, wxALIGN_LEFT | wxALL, 4)
599    
         propertyBox = wxBoxSizer(wxHORIZONTAL)  
         propertyBox.Add(wxStaticText(self, -1, _("Field: ")),  
             0, wxALIGN_CENTER | wxALL, 4)  
600    
601            #
602            # make field combo box
603            #
604          self.fields = wxComboBox(self, ID_PROPERTY_SELECT, "",          self.fields = wxComboBox(self, ID_PROPERTY_SELECT, "",
605                                       style = wxCB_READONLY)                                       style = wxCB_READONLY)
606    
# Line 571  class Classifier(wxDialog): Line 608  class Classifier(wxDialog):
608          # just assume the first field in case one hasn't been          # just assume the first field in case one hasn't been
609          # specified in the file.          # specified in the file.
610          self.__cur_field = 0          self.__cur_field = 0
         clazz = layer.GetClassification()  
         field = clazz.GetField()  
611    
612          self.fields.Append("<None>")          self.fields.Append("<None>")
613          self.fields.SetClientData(0, None)          self.fields.SetClientData(0, None)
# Line 583  class Classifier(wxDialog): Line 618  class Classifier(wxDialog):
618    
619              if name == field:              if name == field:
620                  self.__cur_field = i + 1                  self.__cur_field = i + 1
621                  self.fields.SetClientData(i + 1, clazz)                  self.fields.SetClientData(i + 1, self.originalClass)
622              else:              else:
623                  self.fields.SetClientData(i + 1, None)                  self.fields.SetClientData(i + 1, None)
624    
         self.fields.SetSelection(self.__cur_field)  
625    
626            #
627            #
628            #
629    
630            self.fieldTypeText = wxStaticText(self, -1, "")
631            topBox.Add(self.fieldTypeText, 0, wxGROW | wxALIGN_LEFT | wxALL, 4)
632    
633            propertyBox = wxBoxSizer(wxHORIZONTAL)
634            propertyBox.Add(wxStaticText(self, -1, _("Field: ")),
635                0, wxALIGN_LEFT | wxALL, 4)
636          propertyBox.Add(self.fields, 1, wxGROW|wxALL, 4)          propertyBox.Add(self.fields, 1, wxGROW|wxALL, 4)
637          EVT_COMBOBOX(self, ID_PROPERTY_SELECT, self._OnFieldSelect)          EVT_COMBOBOX(self, ID_PROPERTY_SELECT, self._OnFieldSelect)
638    
# Line 599  class Classifier(wxDialog): Line 643  class Classifier(wxDialog):
643          #          #
644    
645          controlBox = wxBoxSizer(wxHORIZONTAL)          controlBox = wxBoxSizer(wxHORIZONTAL)
         self.classGrid = ClassGrid(self)  
646    
647            self.classGrid = ClassGrid(self)
648          self.__SetGridTable(self.__cur_field)          self.__SetGridTable(self.__cur_field)
649    
650          controlBox.Add(self.classGrid, 1, wxGROW, 0)          controlBox.Add(self.classGrid, 1, wxGROW, 0)
651    
652          controlButtonBox = wxBoxSizer(wxVERTICAL)          controlButtonBox = wxBoxSizer(wxVERTICAL)
         controlButtonBox.Add(wxButton(self, ID_CLASSIFY_ADD,  
             _("Add")), 0, wxGROW | wxALL, 4)  
         controlButtonBox.Add(wxButton(self, ID_CLASSIFY_GENRANGE,  
             _("Generate Ranges")), 0, wxGROW | wxALL, 4)  
   
         controlButtonBox.Add(wxButton(self, ID_CLASSIFY_MOVEUP,  
             _("Move Up")), 0, wxGROW | wxALL, 4)  
         controlButtonBox.Add(wxButton(self, ID_CLASSIFY_MOVEDOWN,  
             _("Move Down")), 0, wxGROW | wxALL, 4)  
653    
654          controlButtonBox.Add(wxButton(self, ID_CLASSIFY_REMOVE,          #
655              _("Remove")), 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)          # Control buttons:
656            #
657            self.controlButtons = []
658    
659            button = wxButton(self, ID_CLASSIFY_ADD, _("Add"))
660            controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
661            self.controlButtons.append(button)
662    
663            #button = wxButton(self, ID_CLASSIFY_GENRANGE, _("Generate Ranges"))
664            #controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
665            #self.controlButtons.append(button)
666    
667            button = wxButton(self, ID_CLASSIFY_MOVEUP, _("Move Up"))
668            controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
669            self.controlButtons.append(button)
670    
671            button = wxButton(self, ID_CLASSIFY_MOVEDOWN, _("Move Down"))
672            controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
673            self.controlButtons.append(button)
674    
675            controlButtonBox.Add(60, 20, 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)
676    
677            button = wxButton(self, ID_CLASSIFY_REMOVE, _("Remove"))
678            controlButtonBox.Add(button, 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)
679            self.controlButtons.append(button)
680    
681          controlBox.Add(controlButtonBox, 0, wxGROW, 10)          controlBox.Add(controlButtonBox, 0, wxGROW, 10)
682          topBox.Add(controlBox, 1, wxGROW, 10)          topBox.Add(controlBox, 1, wxGROW, 10)
# Line 628  class Classifier(wxDialog): Line 687  class Classifier(wxDialog):
687          EVT_BUTTON(self, ID_CLASSIFY_MOVEUP, self._OnMoveUp)          EVT_BUTTON(self, ID_CLASSIFY_MOVEUP, self._OnMoveUp)
688          EVT_BUTTON(self, ID_CLASSIFY_MOVEDOWN, self._OnMoveDown)          EVT_BUTTON(self, ID_CLASSIFY_MOVEDOWN, self._OnMoveDown)
689    
         #  
         # Control buttons:  
         #  
690          buttonBox = wxBoxSizer(wxHORIZONTAL)          buttonBox = wxBoxSizer(wxHORIZONTAL)
691          buttonBox.Add(wxButton(self, ID_CLASSIFY_OK, _("OK")),          buttonBox.Add(wxButton(self, ID_CLASSIFY_OK, _("OK")),
692                        0, wxALL, 4)                        0, wxALL, 4)
693            buttonBox.Add(60, 20, 0, wxALL, 4)
694            buttonBox.Add(wxButton(self, ID_CLASSIFY_APPLY, _("Apply")),
695                          0, wxALL, 4)
696            buttonBox.Add(60, 20, 0, wxALL, 4)
697          buttonBox.Add(wxButton(self, ID_CLASSIFY_CANCEL, _("Cancel")),          buttonBox.Add(wxButton(self, ID_CLASSIFY_CANCEL, _("Cancel")),
698                        0, wxALL, 4)                        0, wxALL, 4)
699          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)
700    
701          EVT_BUTTON(self, ID_CLASSIFY_OK, self._OnOK)          EVT_BUTTON(self, ID_CLASSIFY_OK, self._OnOK)
702            EVT_BUTTON(self, ID_CLASSIFY_APPLY, self._OnApply)
703          EVT_BUTTON(self, ID_CLASSIFY_CANCEL, self._OnCancel)          EVT_BUTTON(self, ID_CLASSIFY_CANCEL, self._OnCancel)
704    
705            self.fields.SetSelection(self.__cur_field)
706            self.__SelectField(self.__cur_field)
707    
708          self.SetAutoLayout(true)          self.SetAutoLayout(true)
709          self.SetSizer(topBox)          self.SetSizer(topBox)
710          topBox.Fit(self)          topBox.Fit(self)
711          topBox.SetSizeHints(self)          topBox.SetSizeHints(self)
712    
713    
714      def __BuildClassification(self, fieldIndex):      def __BuildClassification(self, fieldIndex):
715    
716            numRows = self.classGrid.GetNumberRows()
717            assert(numRows > 0) # there should always be a default row
718    
719          clazz = Classification()          clazz = Classification()
720          fieldName = self.fields.GetString(fieldIndex)          if fieldIndex == 0:
721          fieldType = self.layer.GetFieldType(fieldName)              fieldName = None
722                fieldType = None
723            else:
724                fieldName = self.fields.GetString(fieldIndex)
725                fieldType = self.layer.GetFieldType(fieldName)
726    
727          clazz.SetField(fieldName)          clazz.SetField(fieldName)
728          clazz.SetFieldType(fieldType)          clazz.SetFieldType(fieldType)
729    
         numRows = self.classGrid.GetNumberRows()  
   
         assert(numRows > 0) # there should always be a default row  
730    
731          table = self.classGrid.GetTable()          table = self.classGrid.GetTable()
732          clazz.SetDefaultGroup(table.GetClassGroup(0))          clazz.SetDefaultGroup(table.GetClassGroup(0))
# Line 677  class Classifier(wxDialog): Line 744  class Classifier(wxDialog):
744              clazz = Classification()              clazz = Classification()
745              clazz.SetDefaultGroup(              clazz.SetDefaultGroup(
746                  ClassGroupDefault(                  ClassGroupDefault(
747                      self.layer.GetClassification().GetDefaultGroup().GetProperties()))                      self.layer.GetClassification().
748                                   GetDefaultGroup().GetProperties()))
749    
750              fieldName = self.fields.GetString(fieldIndex)              fieldName = self.fields.GetString(fieldIndex)
751              fieldType = self.layer.GetFieldType(fieldName)              fieldType = self.layer.GetFieldType(fieldName)
# Line 685  class Classifier(wxDialog): Line 753  class Classifier(wxDialog):
753                                    
754          self.classGrid.CreateTable(clazz, self.layer.ShapeType())          self.classGrid.CreateTable(clazz, self.layer.ShapeType())
755    
     def _OnFieldSelect(self, event):  
         clazz = self.__BuildClassification(self.__cur_field)  
         self.fields.SetClientData(self.__cur_field, clazz)  
756    
         self.__cur_field = self.fields.GetSelection()  
         self.__SetGridTable(self.__cur_field)  
757    
758      def _OnOK(self, event):      type2string = {None:             _("None"),
759                       FIELDTYPE_STRING: _("Text"),
760                       FIELDTYPE_INT:    _("Integer"),
761                       FIELDTYPE_DOUBLE: _("Decimal")}
762    
763        def __SetFieldTypeText(self, fieldIndex):
764            fieldName = self.fields.GetString(fieldIndex)
765            fieldType = self.layer.GetFieldType(fieldName)
766    
767            assert(Classifier.type2string.has_key(fieldType))
768    
769            text = Classifier.type2string[fieldType]
770    
771            self.fieldTypeText.SetLabel(_("Field Type: %s") % text)
772    
773        def __SelectField(self, newIndex, oldIndex = -1):
774    
775            assert(oldIndex >= -1)
776    
777            if oldIndex != -1:
778                clazz = self.__BuildClassification(oldIndex)
779                self.fields.SetClientData(oldIndex, clazz)
780    
781            self.__SetGridTable(newIndex)
782    
783            enabled = newIndex != 0
784    
785            for b in self.controlButtons:
786                b.Enable(enabled)
787    
788            self.__SetFieldTypeText(newIndex)
789    
790    
791        def _OnFieldSelect(self, event):
792            index = self.fields.GetSelection()
793            self.__SelectField(index, self.__cur_field)
794            self.__cur_field = index
795    
796        def _OnApply(self, event):
797          """Put the data from the table into a new Classification and hand          """Put the data from the table into a new Classification and hand
798             it to the layer.             it to the layer.
799          """          """
# Line 706  class Classifier(wxDialog): Line 807  class Classifier(wxDialog):
807          if clazz is None or self.classGrid.GetTable().IsModified():          if clazz is None or self.classGrid.GetTable().IsModified():
808              clazz = self.__BuildClassification(self.__cur_field)              clazz = self.__BuildClassification(self.__cur_field)
809    
         clazz.SetLayer(self.layer)  
   
810          self.layer.SetClassification(clazz)          self.layer.SetClassification(clazz)
811    
812          self.EndModal(wxID_OK)      def _OnOK(self, event):
813            self._OnApply(event)
814            self.OnClose(event)
815    
816      def _OnCancel(self, event):      def _OnCancel(self, event):
817          """Do nothing. The layer's current classification stays the same."""          """The layer's current classification stays the same."""
818          self.EndModal(wxID_CANCEL)          self.layer.SetClassification(self.originalClass)
819            self.OnClose(event)
820    
821      def _OnAdd(self, event):      def _OnAdd(self, event):
822          self.classGrid.AppendRows()          self.classGrid.AppendRows()
# Line 760  ID_SELPROP_SPINCTRL = 4002 Line 862  ID_SELPROP_SPINCTRL = 4002
862  ID_SELPROP_PREVIEW = 4003  ID_SELPROP_PREVIEW = 4003
863  ID_SELPROP_STROKECLR = 4004  ID_SELPROP_STROKECLR = 4004
864  ID_SELPROP_FILLCLR = 4005  ID_SELPROP_FILLCLR = 4005
865    ID_SELPROP_STROKECLRTRANS = 4006
866    ID_SELPROP_FILLCLRTRANS = 4007
867    
868  class SelectPropertiesDialog(wxDialog):  class SelectPropertiesDialog(wxDialog):
869    
870      def __init__(self, parent, prop, shapeType):      def __init__(self, parent, prop, shapeType):
871          wxDialog.__init__(self, parent, -1, _("Select Properties"),          wxDialog.__init__(self, parent, -1, _("Select Properties"),
872                            style = wxRESIZE_BORDER)                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
873    
874          self.prop = ClassGroupProperties(prop)          self.prop = ClassGroupProperties(prop)
875    
# Line 785  class SelectPropertiesDialog(wxDialog): Line 889  class SelectPropertiesDialog(wxDialog):
889    
890          # control box          # control box
891          ctrlBox = wxBoxSizer(wxVERTICAL)          ctrlBox = wxBoxSizer(wxVERTICAL)
892          ctrlBox.Add(  
893              wxButton(self, ID_SELPROP_STROKECLR, "Change Line Color"),          lineColorBox = wxBoxSizer(wxHORIZONTAL)
894              0, wxALIGN_CENTER_HORIZONTAL | wxALL | wxGROW, 4)          lineColorBox.Add(
895                wxButton(self, ID_SELPROP_STROKECLR, _("Change Line Color")),
896                1, wxALL | wxGROW, 4)
897          EVT_BUTTON(self, ID_SELPROP_STROKECLR, self._OnChangeLineColor)          EVT_BUTTON(self, ID_SELPROP_STROKECLR, self._OnChangeLineColor)
898    
899            lineColorBox.Add(
900                wxButton(self, ID_SELPROP_STROKECLRTRANS, _("Transparent")),
901                1, wxALL | wxGROW, 4)
902            EVT_BUTTON(self, ID_SELPROP_STROKECLRTRANS,
903                       self._OnChangeLineColorTrans)
904    
905            ctrlBox.Add(lineColorBox, 0,
906                        wxALIGN_CENTER_HORIZONTAL | wxALL | wxGROW, 4)
907    
908          if shapeType != SHAPETYPE_ARC:          if shapeType != SHAPETYPE_ARC:
909              ctrlBox.Add(              fillColorBox = wxBoxSizer(wxHORIZONTAL)
910                  wxButton(self, ID_SELPROP_FILLCLR, "Change Fill Color"),              fillColorBox.Add(
911                  0, wxALIGN_LEFT | wxALL | wxGROW, 4)                  wxButton(self, ID_SELPROP_FILLCLR, _("Change Fill Color")),
912                    1, wxALL | wxGROW, 4)
913              EVT_BUTTON(self, ID_SELPROP_FILLCLR, self._OnChangeFillColor)              EVT_BUTTON(self, ID_SELPROP_FILLCLR, self._OnChangeFillColor)
914                fillColorBox.Add(
915                    wxButton(self, ID_SELPROP_FILLCLRTRANS, _("Transparent")),
916                    1, wxALL | wxGROW, 4)
917                EVT_BUTTON(self, ID_SELPROP_FILLCLRTRANS,
918                           self._OnChangeFillColorTrans)
919                ctrlBox.Add(fillColorBox, 0,
920                            wxALIGN_CENTER_HORIZONTAL | wxALL | wxGROW, 4)
921    
922          spinBox = wxBoxSizer(wxHORIZONTAL)          spinBox = wxBoxSizer(wxHORIZONTAL)
923          spinBox.Add(wxStaticText(self, -1, _("Line Width: ")),          spinBox.Add(wxStaticText(self, -1, _("Line Width: ")),
# Line 812  class SelectPropertiesDialog(wxDialog): Line 935  class SelectPropertiesDialog(wxDialog):
935          itemBox.Add(ctrlBox, 0, wxALIGN_RIGHT | wxALL | wxGROW, 0)          itemBox.Add(ctrlBox, 0, wxALIGN_RIGHT | wxALL | wxGROW, 0)
936          topBox.Add(itemBox, 1, wxALIGN_LEFT | wxALL | wxGROW, 0)          topBox.Add(itemBox, 1, wxALIGN_LEFT | wxALL | wxGROW, 0)
937    
   
938          #          #
939          # Control buttons:          # Control buttons:
940          #          #
941          buttonBox = wxBoxSizer(wxHORIZONTAL)          buttonBox = wxBoxSizer(wxHORIZONTAL)
942          buttonBox.Add(wxButton(self, ID_CLASSIFY_OK, _("OK")),          buttonBox.Add(wxButton(self, ID_SELPROP_OK, _("OK")),
943                        0, wxALL, 4)                        0, wxALL, 4)
944          buttonBox.Add(wxButton(self, ID_CLASSIFY_CANCEL, _("Cancel")),          buttonBox.Add(wxButton(self, ID_SELPROP_CANCEL, _("Cancel")),
945                        0, wxALL, 4)                        0, wxALL, 4)
946          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)
947                                                                                                                                                                    
# Line 858  class SelectPropertiesDialog(wxDialog): Line 980  class SelectPropertiesDialog(wxDialog):
980              self.prop.SetLineColor(clr)              self.prop.SetLineColor(clr)
981          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer
982    
983        def _OnChangeLineColorTrans(self, event):
984            self.prop.SetLineColor(Color.None)
985            self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer
986            
987      def _OnChangeFillColor(self, event):      def _OnChangeFillColor(self, event):
988          clr = self.__GetColor(self.prop.GetFill())          clr = self.__GetColor(self.prop.GetFill())
989          if clr is not None:          if clr is not None:
990              self.prop.SetFill(clr)              self.prop.SetFill(clr)
991          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer
992    
993        def _OnChangeFillColorTrans(self, event):
994            self.prop.SetFill(Color.None)
995            self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer
996    
997      def GetClassGroupProperties(self):      def GetClassGroupProperties(self):
998          return self.prop          return self.prop
999    
# Line 938  class ClassRenderer(wxPyGridCellRenderer Line 1068  class ClassRenderer(wxPyGridCellRenderer
1068          self.previewer = ClassDataPreviewer(None, None, shapeType)          self.previewer = ClassDataPreviewer(None, None, shapeType)
1069    
1070      def Draw(self, grid, attr, dc, rect, row, col, isSelected):      def Draw(self, grid, attr, dc, rect, row, col, isSelected):
1071          data = grid.GetTable().GetValueAsCustom(row, col, None)          data = grid.GetTable().GetClassGroup(row)
1072    
1073          dc.SetClippingRegion(rect.GetX(), rect.GetY(),          dc.SetClippingRegion(rect.GetX(), rect.GetY(),
1074                               rect.GetWidth(), rect.GetHeight())                               rect.GetWidth(), rect.GetHeight())

Legend:
Removed from v.460  
changed lines
  Added in v.507

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26