/[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 498 by jonathan, Mon Mar 10 11:03:22 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 83  class ClassGrid(wxGrid): Line 89  class ClassGrid(wxGrid):
89          else:          else:
90              table.Reset(clazz, self.shapeType)              table.Reset(clazz, self.shapeType)
91    
92            self.SetSelectionMode(wxGrid.wxGridSelectRows)
93          self.ClearSelection()          self.ClearSelection()
94    
95      def GetCurrentSelection(self):      def GetCurrentSelection(self):
# Line 125  class ClassGrid(wxGrid): Line 132  class ClassGrid(wxGrid):
132          # if only one thing is selected check if it is the default          # if only one thing is selected check if it is the default
133          # data row, because we can't remove that          # data row, because we can't remove that
134          if len(sel) == 1:          if len(sel) == 1:
135              group = self.GetTable().GetValueAsCustom(sel[0], COL_SYMBOL, None)              #group = self.GetTable().GetValueAsCustom(sel[0], COL_SYMBOL, None)
136                group = self.GetTable().GetClassGroup(sel[0])
137              if isinstance(group, ClassGroupDefault):              if isinstance(group, ClassGroupDefault):
138                  wxMessageDialog(self,                  wxMessageDialog(self,
139                                  "The Default group cannot be removed.",                                  "The Default group cannot be removed.",
# Line 174  class ClassGrid(wxGrid): Line 182  class ClassGrid(wxGrid):
182          r = event.GetRow()          r = event.GetRow()
183          c = event.GetCol()          c = event.GetCol()
184          if c == COL_SYMBOL:          if c == COL_SYMBOL:
185              group = self.GetTable().GetValueAsCustom(r, c, None)              prop = self.GetTable().GetValueAsCustom(r, c, None)
186              prop = group.GetProperties()              #prop = group.GetProperties()
187    
188              # get a new ClassGroupProperties object and copy the              # get a new ClassGroupProperties object and copy the
189              # values over to our current object              # values over to our current object
190              propDlg = SelectPropertiesDialog(NULL, prop, self.shapeType)              propDlg = SelectPropertiesDialog(NULL, prop, self.shapeType)
191              if propDlg.ShowModal() == wxID_OK:              if propDlg.ShowModal() == wxID_OK:
192                  new_prop = propDlg.GetClassGroupProperties()                  new_prop = propDlg.GetClassGroupProperties()
193                  prop.SetProperties(new_prop)                  #prop.SetProperties(new_prop)
194                  self.Refresh()                  self.GetTable().SetValueAsCustom(r, c, None, new_prop)
195              propDlg.Destroy()              propDlg.Destroy()
196    
197      #      #
# Line 227  class ClassTable(wxPyGridTableBase): Line 235  class ClassTable(wxPyGridTableBase):
235          """          """
236    
237          wxPyGridTableBase.__init__(self)          wxPyGridTableBase.__init__(self)
238    
239          self.SetView(view)          self.SetView(view)
240          self.tdata = []          self.tdata = []
241    
# Line 250  class ClassTable(wxPyGridTableBase): Line 259  class ClassTable(wxPyGridTableBase):
259    
260          self.GetView().BeginBatch()          self.GetView().BeginBatch()
261    
262          self.clazz = clazz          self.fieldType = clazz.GetFieldType()
263          self.shapeType = shapeType          self.shapeType = shapeType
         self.renderer = ClassRenderer(self.shapeType)  
264    
265          old_len = len(self.tdata)          old_len = len(self.tdata)
266    
# Line 262  class ClassTable(wxPyGridTableBase): Line 270  class ClassTable(wxPyGridTableBase):
270          # copy the data out of the classification and into our          # copy the data out of the classification and into our
271          # array          # array
272          #          #
273          for p in self.clazz:          for p in clazz:
274              np = copy.copy(p)              np = copy.deepcopy(p)
275              self.__SetRow(-1, np)              self.__SetRow(-1, np)
276    
277    
278          self.__Modified(False)          self.__Modified(-1)
279    
280          self.__NotifyRowChanges(old_len, len(self.tdata))          self.__NotifyRowChanges(old_len, len(self.tdata))
281    
282            view = self.GetView()
283            w = view.GetDefaultColSize() * 3 + view.GetDefaultRowLabelSize()
284            h = view.GetDefaultRowSize() * 4 + view.GetDefaultColLabelSize()
285            view.SetDimensions(-1, -1, w, h)
286            view.SetSizeHints(w, h, -1, -1)
287                
288          self.GetView().EndBatch()          self.GetView().EndBatch()
289    
290      def __NotifyRowChanges(self, curRows, newRows):      def __NotifyRowChanges(self, curRows, newRows):
# Line 292  class ClassTable(wxPyGridTableBase): Line 307  class ClassTable(wxPyGridTableBase):
307      def __SetRow(self, row, group):      def __SetRow(self, row, group):
308          """Set a row's data to that of the group.          """Set a row's data to that of the group.
309    
310            The table is considered modified after this operation.
311    
312          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
313                 then group is appended to the end.                 then group is appended to the end.
314          """          """
# Line 356  class ClassTable(wxPyGridTableBase): Line 373  class ClassTable(wxPyGridTableBase):
373          group = self.tdata[row]          group = self.tdata[row]
374    
375          if col == COL_SYMBOL:          if col == COL_SYMBOL:
376              return group              return group.GetProperties()
377    
378          if col == COL_LABEL:          if col == COL_LABEL:
379              return group.GetLabel()              return group.GetLabel()
# Line 382  class ClassTable(wxPyGridTableBase): Line 399  class ClassTable(wxPyGridTableBase):
399          value, or of length two if it is a range.          value, or of length two if it is a range.
400          """          """
401    
402          type = self.clazz.GetFieldType()          type = self.fieldType
403    
404          if type == FIELDTYPE_STRING:          if type == FIELDTYPE_STRING:
405              return (value,)              return (value,)
# Line 412  class ClassTable(wxPyGridTableBase): Line 429  class ClassTable(wxPyGridTableBase):
429                  return (conv(Str2Num(value[:i])), conv(Str2Num(value[i+1:])))                  return (conv(Str2Num(value[:i])), conv(Str2Num(value[i+1:])))
430    
431          assert(False) # shouldn't get here          assert(False) # shouldn't get here
432            return (0,)
433                            
434    
435      def SetValueAsCustom(self, row, col, typeName, value):      def SetValueAsCustom(self, row, col, typeName, value):
# Line 431  class ClassTable(wxPyGridTableBase): Line 449  class ClassTable(wxPyGridTableBase):
449    
450          group = self.tdata[row]          group = self.tdata[row]
451    
452          mod = False          mod = True # assume the data will change
453    
454          if col == COL_SYMBOL:          if col == COL_SYMBOL:
455              self.__SetRow(row, value)              group.SetProperties(value)
456              mod = True          elif col == COL_LABEL:
457                group.SetLabel(value)
458          elif col == COL_VALUE:          elif col == COL_VALUE:
459              if isinstance(group, ClassGroupDefault):              if isinstance(group, ClassGroupDefault):
460                  # not allowed to modify the default value                  # not allowed to modify the default value
# Line 448  class ClassTable(wxPyGridTableBase): Line 467  class ClassTable(wxPyGridTableBase):
467                      dataInfo = self.__ParseInput(value)                      dataInfo = self.__ParseInput(value)
468                  except ValueError:                  except ValueError:
469                      # bad input, ignore the request                      # bad input, ignore the request
470                      pass                      mod = False
471                  else:                  else:
472    
473                        changed = False
474                      ngroup = group                      ngroup = group
475                      props = group.GetProperties()                      props = group.GetProperties()
476    
# Line 462  class ClassTable(wxPyGridTableBase): Line 482  class ClassTable(wxPyGridTableBase):
482                      if len(dataInfo) == 1:                      if len(dataInfo) == 1:
483                          if not isinstance(group, ClassGroupSingleton):                          if not isinstance(group, ClassGroupSingleton):
484                              ngroup = ClassGroupSingleton(prop = props)                              ngroup = ClassGroupSingleton(prop = props)
485                                changed = True
486                          ngroup.SetValue(dataInfo[0])                          ngroup.SetValue(dataInfo[0])
487                      elif len(dataInfo) == 2:                      elif len(dataInfo) == 2:
488                          if not isinstance(group, ClassGroupRange):                          if not isinstance(group, ClassGroupRange):
489                              ngroup = ClassGroupRange(prop = props)                              ngroup = ClassGroupRange(prop = props)
490                                changed = True
491                          ngroup.SetRange(dataInfo[0], dataInfo[1])                          ngroup.SetRange(dataInfo[0], dataInfo[1])
492                      else:                      else:
493                          assert(False)                          assert(False)
494                            pass
495    
496                      ngroup.SetLabel(group.GetLabel())                      if changed:
497                            ngroup.SetLabel(group.GetLabel())
498                      self.__SetRow(row, ngroup)                          self.SetClassGroup(row, ngroup)
499            else:
500                      mod = True              assert(False) # shouldn't be here
501                pass
   
         elif col == COL_LABEL:  
             group.SetLabel(value)  
             mod = True  
502    
503          if mod:          if mod:
504              self.__Modified()              self.__Modified()
505              self.GetView().Refresh()              self.GetView().Refresh()
506    
# Line 492  class ClassTable(wxPyGridTableBase): Line 511  class ClassTable(wxPyGridTableBase):
511          #attr = wxPyGridTableBase.GetAttr(self, row, col, someExtraParameter)          #attr = wxPyGridTableBase.GetAttr(self, row, col, someExtraParameter)
512    
513          if col == COL_SYMBOL:          if col == COL_SYMBOL:
514                # we need to create a new renderer each time, because
515                # SetRenderer takes control of the parameter
516              attr.SetRenderer(ClassRenderer(self.shapeType))              attr.SetRenderer(ClassRenderer(self.shapeType))
517              attr.SetReadOnly()              attr.SetReadOnly()
518    
# Line 500  class ClassTable(wxPyGridTableBase): Line 521  class ClassTable(wxPyGridTableBase):
521      def GetClassGroup(self, row):      def GetClassGroup(self, row):
522          """Return the ClassGroup object representing row 'row'."""          """Return the ClassGroup object representing row 'row'."""
523    
524          return self.GetValueAsCustom(row, COL_SYMBOL, None)          return self.tdata[row] # self.GetValueAsCustom(row, COL_SYMBOL, None)
525    
526      def SetClassGroup(self, row, group):      def SetClassGroup(self, row, group):
527          self.SetValueAsCustom(row, COL_SYMBOL, None, group)          self.__SetRow(row, group)
528            self.GetView().Refresh()
529    
530      def __Modified(self, mod = True):      def __Modified(self, mod = True):
531          """Set the modified flag."""          """Adjust the modified flag.
532          self.modified = mod  
533            mod -- if -1 set the modified flag to False, otherwise perform
534                   an 'or' operation with the current value of the flag and
535                   'mod'
536            """
537    
538            if mod == -1:
539                self.modified = False
540            else:
541                self.modified = mod or self.modified
542    
543      def IsModified(self):      def IsModified(self):
544          """True if this table is considered modified."""          """True if this table is considered modified."""
545          return self.modified          return self.modified
546    
547      def DeleteRows(self, pos, numRows = 1):      def DeleteRows(self, pos, numRows = 1):
548          """Deletes 'numRows' beginning at row 'pos'.          """Deletes 'numRows' beginning at row 'pos'.
549    
550          The table is considered modified after this operation.          The row representing the default group is not removed.
551    
552            The table is considered modified if any rows are removed.
553          """          """
554    
555          assert(pos >= 0)          assert(pos >= 0)
556          old_len = len(self.tdata)          old_len = len(self.tdata)
557          for row in range(pos, pos - numRows, -1):          for row in range(pos, pos - numRows, -1):
558              group = self.GetValueAsCustom(row, COL_SYMBOL, None)              group = self.GetClassGroup(row)
559              if not isinstance(group, ClassGroupDefault):              if not isinstance(group, ClassGroupDefault):
560                  self.tdata.pop(row)                  self.tdata.pop(row)
561                  self.__Modified()                  self.__Modified()
# Line 531  class ClassTable(wxPyGridTableBase): Line 564  class ClassTable(wxPyGridTableBase):
564              self.__NotifyRowChanges(old_len, len(self.tdata))              self.__NotifyRowChanges(old_len, len(self.tdata))
565    
566      def AppendRows(self, numRows = 1):      def AppendRows(self, numRows = 1):
567          """Append 'numRows' empty rows to the end of the table."""          """Append 'numRows' empty rows to the end of the table.
568    
569            The table is considered modified if any rows are appended.
570            """
571    
572          old_len = len(self.tdata)          old_len = len(self.tdata)
573          for i in range(numRows):          for i in range(numRows):
574              np = ClassGroupSingleton()              np = ClassGroupSingleton()
575              self.__SetRow(-1, np)              self.__SetRow(-1, np)
             #self.tdata.append([np, np.GetValue(), np.GetLabel()])  
             self.__Modified()  
576    
577          if self.IsModified():          if self.IsModified():
578              self.__NotifyRowChanges(old_len, len(self.tdata))              self.__NotifyRowChanges(old_len, len(self.tdata))
579    
580    
581  class Classifier(wxDialog):  class Classifier(NonModalDialog):
582            
583      def __init__(self, parent, layer):      def __init__(self, parent, interactor, name, layer):
584          wxDialog.__init__(self, parent, -1, _("Classify"),          NonModalDialog.__init__(self, parent, interactor, name,
585                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)                                  _("Classifier: %s") % layer.Title())
   
586    
587          self.layer = layer          self.layer = layer
588    
589            self.originalClass = self.layer.GetClassification()
590            field = self.originalClass.GetField()
591            fieldType = self.originalClass.GetFieldType()
592    
593          topBox = wxBoxSizer(wxVERTICAL)          topBox = wxBoxSizer(wxVERTICAL)
594    
595          topBox.Add(wxStaticText(self, -1, _("Layer: %s") % layer.Title()),          #topBox.Add(wxStaticText(self, -1, _("Layer: %s") % layer.Title()),
596              0, wxALIGN_LEFT | wxALL, 4)              #0, wxALIGN_LEFT | wxALL, 4)
597          topBox.Add(wxStaticText(self, -1, _("Type: %s") % layer.ShapeType()),          topBox.Add(wxStaticText(self, -1,
598                                    _("Layer Type: %s") % layer.ShapeType()),
599              0, wxALIGN_LEFT | wxALL, 4)              0, wxALIGN_LEFT | wxALL, 4)
600    
         propertyBox = wxBoxSizer(wxHORIZONTAL)  
         propertyBox.Add(wxStaticText(self, -1, _("Field: ")),  
             0, wxALIGN_CENTER | wxALL, 4)  
601    
602            #
603            # make field combo box
604            #
605          self.fields = wxComboBox(self, ID_PROPERTY_SELECT, "",          self.fields = wxComboBox(self, ID_PROPERTY_SELECT, "",
606                                       style = wxCB_READONLY)                                       style = wxCB_READONLY)
607    
# Line 571  class Classifier(wxDialog): Line 609  class Classifier(wxDialog):
609          # just assume the first field in case one hasn't been          # just assume the first field in case one hasn't been
610          # specified in the file.          # specified in the file.
611          self.__cur_field = 0          self.__cur_field = 0
         clazz = layer.GetClassification()  
         field = clazz.GetField()  
612    
613          self.fields.Append("<None>")          self.fields.Append("<None>")
614          self.fields.SetClientData(0, None)          self.fields.SetClientData(0, None)
# Line 583  class Classifier(wxDialog): Line 619  class Classifier(wxDialog):
619    
620              if name == field:              if name == field:
621                  self.__cur_field = i + 1                  self.__cur_field = i + 1
622                  self.fields.SetClientData(i + 1, clazz)                  self.fields.SetClientData(i + 1, self.originalClass)
623              else:              else:
624                  self.fields.SetClientData(i + 1, None)                  self.fields.SetClientData(i + 1, None)
625    
         self.fields.SetSelection(self.__cur_field)  
626    
627            #
628            #
629            #
630    
631            self.fieldTypeText = wxStaticText(self, -1, "")
632            self.__SetFieldTypeText(self.__cur_field)
633    
634            topBox.Add(self.fieldTypeText, 0, wxALIGN_LEFT | wxALL, 4)
635            #self.fieldTypeText.SetLabel("asdfadsfs")
636    
637            propertyBox = wxBoxSizer(wxHORIZONTAL)
638            propertyBox.Add(wxStaticText(self, -1, _("Field: ")),
639                0, wxALIGN_CENTER | wxALL, 4)
640          propertyBox.Add(self.fields, 1, wxGROW|wxALL, 4)          propertyBox.Add(self.fields, 1, wxGROW|wxALL, 4)
641          EVT_COMBOBOX(self, ID_PROPERTY_SELECT, self._OnFieldSelect)          EVT_COMBOBOX(self, ID_PROPERTY_SELECT, self._OnFieldSelect)
642    
# Line 599  class Classifier(wxDialog): Line 647  class Classifier(wxDialog):
647          #          #
648    
649          controlBox = wxBoxSizer(wxHORIZONTAL)          controlBox = wxBoxSizer(wxHORIZONTAL)
         self.classGrid = ClassGrid(self)  
650    
651            self.classGrid = ClassGrid(self)
652          self.__SetGridTable(self.__cur_field)          self.__SetGridTable(self.__cur_field)
653    
654          controlBox.Add(self.classGrid, 1, wxGROW, 0)          controlBox.Add(self.classGrid, 1, wxGROW, 0)
655    
656          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)  
657    
658          controlButtonBox.Add(wxButton(self, ID_CLASSIFY_REMOVE,          #
659              _("Remove")), 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)          # Control buttons:
660            #
661            self.controlButtons = []
662    
663            button = wxButton(self, ID_CLASSIFY_ADD, _("Add"))
664            controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
665            self.controlButtons.append(button)
666    
667            #button = wxButton(self, ID_CLASSIFY_GENRANGE, _("Generate Ranges"))
668            #controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
669            #self.controlButtons.append(button)
670    
671            button = wxButton(self, ID_CLASSIFY_MOVEUP, _("Move Up"))
672            controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
673            self.controlButtons.append(button)
674    
675            button = wxButton(self, ID_CLASSIFY_MOVEDOWN, _("Move Down"))
676            controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
677            self.controlButtons.append(button)
678    
679            controlButtonBox.Add(60, 20, 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)
680    
681            button = wxButton(self, ID_CLASSIFY_REMOVE, _("Remove"))
682            controlButtonBox.Add(button, 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)
683            self.controlButtons.append(button)
684    
685          controlBox.Add(controlButtonBox, 0, wxGROW, 10)          controlBox.Add(controlButtonBox, 0, wxGROW, 10)
686          topBox.Add(controlBox, 1, wxGROW, 10)          topBox.Add(controlBox, 1, wxGROW, 10)
# Line 628  class Classifier(wxDialog): Line 691  class Classifier(wxDialog):
691          EVT_BUTTON(self, ID_CLASSIFY_MOVEUP, self._OnMoveUp)          EVT_BUTTON(self, ID_CLASSIFY_MOVEUP, self._OnMoveUp)
692          EVT_BUTTON(self, ID_CLASSIFY_MOVEDOWN, self._OnMoveDown)          EVT_BUTTON(self, ID_CLASSIFY_MOVEDOWN, self._OnMoveDown)
693    
         #  
         # Control buttons:  
         #  
694          buttonBox = wxBoxSizer(wxHORIZONTAL)          buttonBox = wxBoxSizer(wxHORIZONTAL)
695          buttonBox.Add(wxButton(self, ID_CLASSIFY_OK, _("OK")),          buttonBox.Add(wxButton(self, ID_CLASSIFY_OK, _("OK")),
696                        0, wxALL, 4)                        0, wxALL, 4)
697            buttonBox.Add(60, 20, 0, wxALL, 4)
698            buttonBox.Add(wxButton(self, ID_CLASSIFY_APPLY, _("Apply")),
699                          0, wxALL, 4)
700            buttonBox.Add(60, 20, 0, wxALL, 4)
701          buttonBox.Add(wxButton(self, ID_CLASSIFY_CANCEL, _("Cancel")),          buttonBox.Add(wxButton(self, ID_CLASSIFY_CANCEL, _("Cancel")),
702                        0, wxALL, 4)                        0, wxALL, 4)
703          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)
704    
705          EVT_BUTTON(self, ID_CLASSIFY_OK, self._OnOK)          EVT_BUTTON(self, ID_CLASSIFY_OK, self._OnOK)
706            EVT_BUTTON(self, ID_CLASSIFY_APPLY, self._OnApply)
707          EVT_BUTTON(self, ID_CLASSIFY_CANCEL, self._OnCancel)          EVT_BUTTON(self, ID_CLASSIFY_CANCEL, self._OnCancel)
708    
709            self.fields.SetSelection(self.__cur_field)
710            self.__SelectField(self.__cur_field)
711    
712          self.SetAutoLayout(true)          self.SetAutoLayout(true)
713          self.SetSizer(topBox)          self.SetSizer(topBox)
714          topBox.Fit(self)          topBox.Fit(self)
715          topBox.SetSizeHints(self)          topBox.SetSizeHints(self)
716    
717    
718      def __BuildClassification(self, fieldIndex):      def __BuildClassification(self, fieldIndex):
719    
720            numRows = self.classGrid.GetNumberRows()
721            assert(numRows > 0) # there should always be a default row
722    
723          clazz = Classification()          clazz = Classification()
724          fieldName = self.fields.GetString(fieldIndex)          if fieldIndex == 0:
725          fieldType = self.layer.GetFieldType(fieldName)              fieldName = None
726                fieldType = None
727            else:
728                fieldName = self.fields.GetString(fieldIndex)
729                fieldType = self.layer.GetFieldType(fieldName)
730    
731          clazz.SetField(fieldName)          clazz.SetField(fieldName)
732          clazz.SetFieldType(fieldType)          clazz.SetFieldType(fieldType)
733    
         numRows = self.classGrid.GetNumberRows()  
   
         assert(numRows > 0) # there should always be a default row  
734    
735          table = self.classGrid.GetTable()          table = self.classGrid.GetTable()
736          clazz.SetDefaultGroup(table.GetClassGroup(0))          clazz.SetDefaultGroup(table.GetClassGroup(0))
# Line 677  class Classifier(wxDialog): Line 748  class Classifier(wxDialog):
748              clazz = Classification()              clazz = Classification()
749              clazz.SetDefaultGroup(              clazz.SetDefaultGroup(
750                  ClassGroupDefault(                  ClassGroupDefault(
751                      self.layer.GetClassification().GetDefaultGroup().GetProperties()))                      self.layer.GetClassification().
752                                   GetDefaultGroup().GetProperties()))
753    
754              fieldName = self.fields.GetString(fieldIndex)              fieldName = self.fields.GetString(fieldIndex)
755              fieldType = self.layer.GetFieldType(fieldName)              fieldType = self.layer.GetFieldType(fieldName)
# Line 685  class Classifier(wxDialog): Line 757  class Classifier(wxDialog):
757                                    
758          self.classGrid.CreateTable(clazz, self.layer.ShapeType())          self.classGrid.CreateTable(clazz, self.layer.ShapeType())
759    
     def _OnFieldSelect(self, event):  
         clazz = self.__BuildClassification(self.__cur_field)  
         self.fields.SetClientData(self.__cur_field, clazz)  
760    
         self.__cur_field = self.fields.GetSelection()  
         self.__SetGridTable(self.__cur_field)  
761    
762      def _OnOK(self, event):      type2string = {None:             "None",
763                       FIELDTYPE_STRING: "Text",
764                       FIELDTYPE_INT:    "Integer",
765                       FIELDTYPE_DOUBLE: "Decimal"}
766    
767        def __SetFieldTypeText(self, fieldIndex):
768            fieldName = self.fields.GetString(fieldIndex)
769            fieldType = self.layer.GetFieldType(fieldName)
770    
771            assert(Classifier.type2string.has_key(fieldType))
772    
773            text = Classifier.type2string[fieldType]
774    
775            self.fieldTypeText.SetLabel(_("Field Type: %s") % text)
776    
777        def __SelectField(self, newIndex, oldIndex = -1):
778    
779            assert(oldIndex >= -1)
780    
781            if oldIndex != -1:
782                clazz = self.__BuildClassification(oldIndex)
783                self.fields.SetClientData(oldIndex, clazz)
784    
785            self.__SetGridTable(newIndex)
786    
787            enabled = newIndex != 0
788    
789            for b in self.controlButtons:
790                b.Enable(enabled)
791    
792            self.__SetFieldTypeText(newIndex)
793    
794    
795        def _OnFieldSelect(self, event):
796            index = self.fields.GetSelection()
797            self.__SelectField(index, self.__cur_field)
798            self.__cur_field = index
799    
800        def _OnApply(self, event):
801          """Put the data from the table into a new Classification and hand          """Put the data from the table into a new Classification and hand
802             it to the layer.             it to the layer.
803          """          """
# Line 706  class Classifier(wxDialog): Line 811  class Classifier(wxDialog):
811          if clazz is None or self.classGrid.GetTable().IsModified():          if clazz is None or self.classGrid.GetTable().IsModified():
812              clazz = self.__BuildClassification(self.__cur_field)              clazz = self.__BuildClassification(self.__cur_field)
813    
         clazz.SetLayer(self.layer)  
   
814          self.layer.SetClassification(clazz)          self.layer.SetClassification(clazz)
815    
816          self.EndModal(wxID_OK)      def _OnOK(self, event):
817            self._OnApply(event)
818            self.OnClose(event)
819    
820      def _OnCancel(self, event):      def _OnCancel(self, event):
821          """Do nothing. The layer's current classification stays the same."""          """The layer's current classification stays the same."""
822          self.EndModal(wxID_CANCEL)          self.layer.SetClassification(self.originalClass)
823            self.OnClose(event)
824    
825      def _OnAdd(self, event):      def _OnAdd(self, event):
826          self.classGrid.AppendRows()          self.classGrid.AppendRows()
# Line 760  ID_SELPROP_SPINCTRL = 4002 Line 866  ID_SELPROP_SPINCTRL = 4002
866  ID_SELPROP_PREVIEW = 4003  ID_SELPROP_PREVIEW = 4003
867  ID_SELPROP_STROKECLR = 4004  ID_SELPROP_STROKECLR = 4004
868  ID_SELPROP_FILLCLR = 4005  ID_SELPROP_FILLCLR = 4005
869    ID_SELPROP_STROKECLRTRANS = 4006
870    ID_SELPROP_FILLCLRTRANS = 4007
871    
872  class SelectPropertiesDialog(wxDialog):  class SelectPropertiesDialog(wxDialog):
873    
# Line 785  class SelectPropertiesDialog(wxDialog): Line 893  class SelectPropertiesDialog(wxDialog):
893    
894          # control box          # control box
895          ctrlBox = wxBoxSizer(wxVERTICAL)          ctrlBox = wxBoxSizer(wxVERTICAL)
896          ctrlBox.Add(  
897            lineColorBox = wxBoxSizer(wxHORIZONTAL)
898            lineColorBox.Add(
899              wxButton(self, ID_SELPROP_STROKECLR, "Change Line Color"),              wxButton(self, ID_SELPROP_STROKECLR, "Change Line Color"),
900              0, wxALIGN_CENTER_HORIZONTAL | wxALL | wxGROW, 4)              1, wxALL | wxGROW, 4)
901          EVT_BUTTON(self, ID_SELPROP_STROKECLR, self._OnChangeLineColor)          EVT_BUTTON(self, ID_SELPROP_STROKECLR, self._OnChangeLineColor)
902    
903            lineColorBox.Add(
904                wxButton(self, ID_SELPROP_STROKECLRTRANS, "Transparent"),
905                1, wxALL | wxGROW, 4)
906            EVT_BUTTON(self, ID_SELPROP_STROKECLRTRANS,
907                       self._OnChangeLineColorTrans)
908    
909            ctrlBox.Add(lineColorBox, 0,
910                        wxALIGN_CENTER_HORIZONTAL | wxALL | wxGROW, 4)
911    
912          if shapeType != SHAPETYPE_ARC:          if shapeType != SHAPETYPE_ARC:
913              ctrlBox.Add(              fillColorBox = wxBoxSizer(wxHORIZONTAL)
914                fillColorBox.Add(
915                  wxButton(self, ID_SELPROP_FILLCLR, "Change Fill Color"),                  wxButton(self, ID_SELPROP_FILLCLR, "Change Fill Color"),
916                  0, wxALIGN_LEFT | wxALL | wxGROW, 4)                  1, wxALL | wxGROW, 4)
917              EVT_BUTTON(self, ID_SELPROP_FILLCLR, self._OnChangeFillColor)              EVT_BUTTON(self, ID_SELPROP_FILLCLR, self._OnChangeFillColor)
918                fillColorBox.Add(
919                    wxButton(self, ID_SELPROP_FILLCLRTRANS, "Transparent"),
920                    1, wxALL | wxGROW, 4)
921                EVT_BUTTON(self, ID_SELPROP_FILLCLRTRANS,
922                           self._OnChangeFillColorTrans)
923                ctrlBox.Add(fillColorBox, 0,
924                            wxALIGN_CENTER_HORIZONTAL | wxALL | wxGROW, 4)
925    
926          spinBox = wxBoxSizer(wxHORIZONTAL)          spinBox = wxBoxSizer(wxHORIZONTAL)
927          spinBox.Add(wxStaticText(self, -1, _("Line Width: ")),          spinBox.Add(wxStaticText(self, -1, _("Line Width: ")),
# Line 812  class SelectPropertiesDialog(wxDialog): Line 939  class SelectPropertiesDialog(wxDialog):
939          itemBox.Add(ctrlBox, 0, wxALIGN_RIGHT | wxALL | wxGROW, 0)          itemBox.Add(ctrlBox, 0, wxALIGN_RIGHT | wxALL | wxGROW, 0)
940          topBox.Add(itemBox, 1, wxALIGN_LEFT | wxALL | wxGROW, 0)          topBox.Add(itemBox, 1, wxALIGN_LEFT | wxALL | wxGROW, 0)
941    
   
942          #          #
943          # Control buttons:          # Control buttons:
944          #          #
945          buttonBox = wxBoxSizer(wxHORIZONTAL)          buttonBox = wxBoxSizer(wxHORIZONTAL)
946          buttonBox.Add(wxButton(self, ID_CLASSIFY_OK, _("OK")),          buttonBox.Add(wxButton(self, ID_SELPROP_OK, _("OK")),
947                        0, wxALL, 4)                        0, wxALL, 4)
948          buttonBox.Add(wxButton(self, ID_CLASSIFY_CANCEL, _("Cancel")),          buttonBox.Add(wxButton(self, ID_SELPROP_CANCEL, _("Cancel")),
949                        0, wxALL, 4)                        0, wxALL, 4)
950          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)
951                                                                                                                                                                    
# Line 858  class SelectPropertiesDialog(wxDialog): Line 984  class SelectPropertiesDialog(wxDialog):
984              self.prop.SetLineColor(clr)              self.prop.SetLineColor(clr)
985          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer
986    
987        def _OnChangeLineColorTrans(self, event):
988            self.prop.SetLineColor(Color.None)
989            self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer
990            
991      def _OnChangeFillColor(self, event):      def _OnChangeFillColor(self, event):
992          clr = self.__GetColor(self.prop.GetFill())          clr = self.__GetColor(self.prop.GetFill())
993          if clr is not None:          if clr is not None:
994              self.prop.SetFill(clr)              self.prop.SetFill(clr)
995          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer
996    
997        def _OnChangeFillColorTrans(self, event):
998            self.prop.SetFill(Color.None)
999            self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer
1000    
1001      def GetClassGroupProperties(self):      def GetClassGroupProperties(self):
1002          return self.prop          return self.prop
1003    
# Line 938  class ClassRenderer(wxPyGridCellRenderer Line 1072  class ClassRenderer(wxPyGridCellRenderer
1072          self.previewer = ClassDataPreviewer(None, None, shapeType)          self.previewer = ClassDataPreviewer(None, None, shapeType)
1073    
1074      def Draw(self, grid, attr, dc, rect, row, col, isSelected):      def Draw(self, grid, attr, dc, rect, row, col, isSelected):
1075          data = grid.GetTable().GetValueAsCustom(row, col, None)          data = grid.GetTable().GetClassGroup(row)
1076    
1077          dc.SetClippingRegion(rect.GetX(), rect.GetY(),          dc.SetClippingRegion(rect.GetX(), rect.GetY(),
1078                               rect.GetWidth(), rect.GetHeight())                               rect.GetWidth(), rect.GetHeight())

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26