/[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 509 by jonathan, Tue Mar 11 09:45:59 2003 UTC revision 611 by jonathan, Fri Apr 4 16:34:46 2003 UTC
# Line 27  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 Thuban.UI.classgen import ClassGenDialog, ClassGenerator
31    
32  from dialogs import NonModalDialog  from dialogs import NonModalDialog
33    
34  # widget id's  # widget id's
# Line 36  ID_CLASS_TABLE = 40011 Line 38  ID_CLASS_TABLE = 40011
38  ID_CLASSIFY_OK = 4001  ID_CLASSIFY_OK = 4001
39  ID_CLASSIFY_CANCEL = 4002  ID_CLASSIFY_CANCEL = 4002
40  ID_CLASSIFY_ADD = 4003  ID_CLASSIFY_ADD = 4003
41  ID_CLASSIFY_GENRANGE = 4004  ID_CLASSIFY_GENCLASS = 4004
42  ID_CLASSIFY_REMOVE = 4005  ID_CLASSIFY_REMOVE = 4005
43  ID_CLASSIFY_MOVEUP = 4006  ID_CLASSIFY_MOVEUP = 4006
44  ID_CLASSIFY_MOVEDOWN = 4007  ID_CLASSIFY_MOVEDOWN = 4007
45  ID_CLASSIFY_APPLY = 4008  ID_CLASSIFY_APPLY = 4008
46    ID_CLASSIFY_EDITPROPS = 4009
47    
48  # table columns  # table columns
49  COL_SYMBOL = 0  COL_SYMBOL = 0
# Line 59  FIELD_NAME = 2 Line 62  FIELD_NAME = 2
62  import weakref  import weakref
63  class ClassGrid(wxGrid):  class ClassGrid(wxGrid):
64    
65      def __init__(self, parent):  
66        def __init__(self, parent, classifier):
67          """Constructor.          """Constructor.
68    
69          parent -- the parent window          parent -- the parent window
# Line 72  class ClassGrid(wxGrid): Line 76  class ClassGrid(wxGrid):
76          wxGrid.__init__(self, parent, ID_CLASS_TABLE)          wxGrid.__init__(self, parent, ID_CLASS_TABLE)
77          #self.SetTable(ClassTable(fieldData, layer.ShapeType(), self), True)          #self.SetTable(ClassTable(fieldData, layer.ShapeType(), self), True)
78    
79            self.classifier = classifier
80    
81            self.currentSelection = []
82    
83          EVT_GRID_CELL_LEFT_DCLICK(self, self._OnCellDClick)          EVT_GRID_CELL_LEFT_DCLICK(self, self._OnCellDClick)
84          EVT_GRID_RANGE_SELECT(self, self._OnSelectedRange)          EVT_GRID_RANGE_SELECT(self, self._OnSelectedRange)
85          EVT_GRID_SELECT_CELL(self, self._OnSelectedCell)          EVT_GRID_SELECT_CELL(self, self._OnSelectedCell)
86            EVT_GRID_COL_SIZE(self, self._OnCellResize)
87            EVT_GRID_ROW_SIZE(self, self._OnCellResize)
88    
89          self.currentSelection = []          #print "123123123: ", ('Show' in dir(self))
90    
91      def CreateTable(self, clazz, shapeType):      #def Show(self):
92            #print "SHOW!"
93    
94          assert(isinstance(clazz, Classification))      #def Refresh(self):
95            #self.Show()
96        #def Update(self):
97            #self.Show()
98    
99        def CreateTable(self, clazz, shapeType, group = None):
100    
101            assert isinstance(clazz, Classification)
102    
         self.shapeType = shapeType  
103          table = self.GetTable()          table = self.GetTable()
104          if table is None:          if table is None:
105              w = self.GetDefaultColSize() * 3 + self.GetDefaultRowLabelSize()              w = self.GetDefaultColSize() * 3 + self.GetDefaultRowLabelSize()
106              h = self.GetDefaultRowSize() * 4 + self.GetDefaultColLabelSize()              h = self.GetDefaultRowSize() * 4 + self.GetDefaultColLabelSize()
107              self.SetDimensions(-1, -1, w, h)              self.SetDimensions(-1, -1, w, h)
108              self.SetSizeHints(w, h, -1, -1)              self.SetSizeHints(w, h, -1, -1)
109              self.SetTable(ClassTable(clazz, self.shapeType, self), True)              table = ClassTable(self)
110          else:              self.SetTable(table, True)
111              table.Reset(clazz, self.shapeType)  
112    
113          self.SetSelectionMode(wxGrid.wxGridSelectRows)          self.SetSelectionMode(wxGrid.wxGridSelectRows)
114          self.ClearSelection()          self.ClearSelection()
115    
116            #print "8------------------"
117            table.Reset(clazz, shapeType, group)
118            #print "9------------------"
119    
120    #   def Show(self, show = True):
121    #       print "SHOW!"
122    #       wxGrid.Show(self, show)
123    
124    #       sel = self.GetCurrentSelection()
125    
126    #       print "( 1"
127    #       if len(sel) == 1:
128    #           print "( 2"
129    #           self.MakeCellVisible(sel[0], 0)
130    
131      def GetCurrentSelection(self):      def GetCurrentSelection(self):
132          """Return the currently highlighted rows as an increasing list          """Return the currently highlighted rows as an increasing list
133             of row numbers."""             of row numbers."""
134            #print "@@ ", self.currentSelection
135          sel = copy.copy(self.currentSelection)          sel = copy.copy(self.currentSelection)
136          sel.sort()          sel.sort()
137          return sel          return sel
138    
139        def GetSelectedRows(self):
140            return self.GetCurrentSelection()
141    
142      def SetCellRenderer(self, row, col):      def SetCellRenderer(self, row, col):
143          raise ValueError(_("Must not allow setting of renderer in ClassGrid!"))          raise ValueError(_("Must not allow setting of renderer in ClassGrid!"))
144    
# Line 169  class ClassGrid(wxGrid): Line 205  class ClassGrid(wxGrid):
205                  r = self.GetNumberRows() - 1                  r = self.GetNumberRows() - 1
206              self.SelectRow(r)              self.SelectRow(r)
207                    
208    
209        def SelectGroup(self, group, makeVisible = True):
210            if group is None: return
211    
212            assert isinstance(group, ClassGroup)
213    
214            table = self.GetTable()
215    
216            assert table is not None
217    
218    
219            #print "-- ", group
220            for i in range(table.GetNumberRows()):
221                g = table.GetClassGroup(i)
222                #print "1", g
223                if g is group:
224                    #print "2"
225                    self.SelectRow(i)
226                    if makeVisible:
227                        #print "3"
228                        self.MakeCellVisible(i, 0)
229                    break
230    
231            
232    
233  #  #
234  # XXX: This isn't working, and there is no way to deselect rows wxPython!  # XXX: This isn't working, and there is no way to deselect rows wxPython!
235  #  #
# Line 186  class ClassGrid(wxGrid): Line 247  class ClassGrid(wxGrid):
247          r = event.GetRow()          r = event.GetRow()
248          c = event.GetCol()          c = event.GetCol()
249          if c == COL_SYMBOL:          if c == COL_SYMBOL:
250              prop = self.GetTable().GetValueAsCustom(r, c, None)              self.classifier.EditGroupProperties(r)
             #prop = group.GetProperties()  
251    
             # get a new ClassGroupProperties object and copy the  
             # values over to our current object  
             propDlg = SelectPropertiesDialog(NULL, prop, self.shapeType)  
             if propDlg.ShowModal() == wxID_OK:  
                 new_prop = propDlg.GetClassGroupProperties()  
                 #prop.SetProperties(new_prop)  
                 self.GetTable().SetValueAsCustom(r, c, None, new_prop)  
             propDlg.Destroy()  
252    
253      #      #
254      # _OnSelectedRange() and _OnSelectedCell() were borrowed      # _OnSelectedRange() and _OnSelectedCell() were borrowed
# Line 208  class ClassGrid(wxGrid): Line 260  class ClassGrid(wxGrid):
260          if event.Selecting():          if event.Selecting():
261              for index in range( event.GetTopRow(), event.GetBottomRow()+1):              for index in range( event.GetTopRow(), event.GetBottomRow()+1):
262                  if index not in self.currentSelection:                  if index not in self.currentSelection:
263                        #print "    ", index
264                      self.currentSelection.append( index )                      self.currentSelection.append( index )
265          else:          else:
266              for index in range( event.GetTopRow(), event.GetBottomRow()+1):              for index in range( event.GetTopRow(), event.GetBottomRow()+1):
267                  while index in self.currentSelection:                  while index in self.currentSelection:
268                        #print "    ", index
269                      self.currentSelection.remove( index )                      self.currentSelection.remove( index )
270          #self.ConfigureForSelection()          #self.ConfigureForSelection()
271    
272            #print self.GetCurrentSelection()
273          event.Skip()          event.Skip()
274    
275      def _OnSelectedCell( self, event ):      def _OnSelectedCell( self, event ):
276          """Internal update to the selection tracking list"""          """Internal update to the selection tracking list"""
277            #print "selecting cell: ", event.GetRow()
278          self.currentSelection = [ event.GetRow() ]          self.currentSelection = [ event.GetRow() ]
279          #self.ConfigureForSelection()          #self.ConfigureForSelection()
280          event.Skip()          event.Skip()
281    
282        def _OnCellResize(self, event):
283            self.FitInside()
284    
285  class ClassTable(wxPyGridTableBase):  class ClassTable(wxPyGridTableBase):
286      """Represents the underlying data structure for the grid."""      """Represents the underlying data structure for the grid."""
287    
# Line 230  class ClassTable(wxPyGridTableBase): Line 289  class ClassTable(wxPyGridTableBase):
289    
290      __col_labels = [_("Symbol"), _("Value"), _("Label")]      __col_labels = [_("Symbol"), _("Value"), _("Label")]
291    
292      def __init__(self, clazz, shapeType, view = None):  
293        def __init__(self, view = None):
294        #def __init__(self, clazz, shapeType, view = None):
295          """Constructor.          """Constructor.
296    
297          shapeType -- the type of shape that the layer uses          shapeType -- the type of shape that the layer uses
# Line 243  class ClassTable(wxPyGridTableBase): Line 304  class ClassTable(wxPyGridTableBase):
304          self.SetView(view)          self.SetView(view)
305          self.tdata = []          self.tdata = []
306    
307          self.Reset(clazz, shapeType)          #self.Reset(clazz, shapeType)
308    
309      def Reset(self, clazz, shapeType):      def Reset(self, clazz, shapeType, group = None):
310          """Reset the table with the given data.          """Reset the table with the given data.
311    
312          This is necessary because wxWindows does not allow a grid's          This is necessary because wxWindows does not allow a grid's
# Line 259  class ClassTable(wxPyGridTableBase): Line 320  class ClassTable(wxPyGridTableBase):
320          shapeType -- the type of shape that the layer uses          shapeType -- the type of shape that the layer uses
321          """          """
322    
323          assert(isinstance(clazz, Classification))          assert isinstance(clazz, Classification)
324    
325          self.GetView().BeginBatch()          self.GetView().BeginBatch()
326    
327          self.fieldType = clazz.GetFieldType()          self.fieldType = clazz.GetFieldType()
328          self.shapeType = shapeType          self.shapeType = shapeType
329    
330          old_len = len(self.tdata)          self.SetClassification(clazz, group)
331            self.__Modified(-1)
332            #print "11------------------"
333    
334            self.GetView().EndBatch()
335            self.GetView().FitInside()
336    
337        def SetClassification(self, clazz, group = None):
338    
339            self.GetView().BeginBatch()
340    
341            old_len = self.GetNumberRows()
342          self.tdata = []          self.tdata = []
343    
344            #print "9------------------"
345          #          #
346          # copy the data out of the classification and into our          # copy the data out of the classification and into our
347          # array          # array
348          #          #
349          for p in clazz:          row = -1
350              np = copy.deepcopy(p)          for g in clazz:
351              self.__SetRow(-1, np)              ng = copy.deepcopy(g)
352                self.__SetRow(None, ng)
353                if g is group:
354                    row = self.GetNumberRows() - 1
355                    #print "selecting row..."
356    
357            #print "10------------------"
358    
359          self.__Modified(-1)          self.__NotifyRowChanges(old_len, self.GetNumberRows())
360    
361          self.__NotifyRowChanges(old_len, len(self.tdata))          if row > -1:
362                self.GetView().ClearSelection()
363                self.GetView().SelectRow(row)
364                self.GetView().MakeCellVisible(row, 0)
365    
               
366          self.GetView().EndBatch()          self.GetView().EndBatch()
367            self.GetView().FitInside()
368    
369      def __NotifyRowChanges(self, curRows, newRows):      def __NotifyRowChanges(self, curRows, newRows):
370          #          #
# Line 296  class ClassTable(wxPyGridTableBase): Line 376  class ClassTable(wxPyGridTableBase):
376                          wxGRIDTABLE_NOTIFY_ROWS_APPENDED,                          wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
377                          newRows - curRows)    # how many                          newRows - curRows)    # how many
378              self.GetView().ProcessTableMessage(msg)              self.GetView().ProcessTableMessage(msg)
379                self.GetView().FitInside()
380          elif newRows < curRows:          elif newRows < curRows:
381              msg = wxGridTableMessage(self,              msg = wxGridTableMessage(self,
382                          wxGRIDTABLE_NOTIFY_ROWS_DELETED,                          wxGRIDTABLE_NOTIFY_ROWS_DELETED,
383                          curRows - newRows,    # position                          curRows,              # position
384                          curRows - newRows)    # how many                          curRows - newRows)    # how many
385              self.GetView().ProcessTableMessage(msg)              self.GetView().ProcessTableMessage(msg)
386                self.GetView().FitInside()
387    
388      def __SetRow(self, row, group):      def __SetRow(self, row, group):
389          """Set a row's data to that of the group.          """Set a row's data to that of the group.
390    
391          The table is considered modified after this operation.          The table is considered modified after this operation.
392    
393          row -- if row is -1 or greater than the current number of rows          row -- if row is < 0 'group' is inserted at the top of the table
394                 then group is appended to the end.                 if row is >= GetNumberRows() or None 'group' is append to
395                        the end of the table.
396                   otherwise 'group' replaces row 'row'
397          """          """
398    
399          # either append or replace          # either append or replace
400          if row == -1 or row >= self.GetNumberRows():          if row is None or row >= self.GetNumberRows():
401              self.tdata.append(group)              self.tdata.append(group)
402            elif row < 0:
403                self.tdata.insert(0, group)
404          else:          else:
405              self.tdata[row] = group              self.tdata[row] = group
406    
# Line 333  class ClassTable(wxPyGridTableBase): Line 419  class ClassTable(wxPyGridTableBase):
419          if isinstance(group, ClassGroupRange):     return _("Range")          if isinstance(group, ClassGroupRange):     return _("Range")
420          if isinstance(group, ClassGroupMap):       return _("Map")          if isinstance(group, ClassGroupMap):       return _("Map")
421    
422          assert(False) # shouldn't get here          assert False # shouldn't get here
423          return _("")          return _("")
424    
425      def GetNumberRows(self):      def GetNumberRows(self):
# Line 378  class ClassTable(wxPyGridTableBase): Line 464  class ClassTable(wxPyGridTableBase):
464              return group.GetLabel()              return group.GetLabel()
465    
466          # col must be COL_VALUE          # col must be COL_VALUE
467          assert(col == COL_VALUE)          assert col == COL_VALUE
468    
469          if isinstance(group, ClassGroupDefault):          if isinstance(group, ClassGroupDefault):
470              return _("DEFAULT")              return _("DEFAULT")
# Line 387  class ClassTable(wxPyGridTableBase): Line 473  class ClassTable(wxPyGridTableBase):
473          elif isinstance(group, ClassGroupRange):          elif isinstance(group, ClassGroupRange):
474              return _("%s - %s") % (group.GetMin(), group.GetMax())              return _("%s - %s") % (group.GetMin(), group.GetMax())
475    
476          assert(False) # shouldn't get here          assert False  # shouldn't get here
477          return None          return None
478    
479      def __ParseInput(self, value):      def __ParseInput(self, value):
# Line 427  class ClassTable(wxPyGridTableBase): Line 513  class ClassTable(wxPyGridTableBase):
513    
514                  return (conv(Str2Num(value[:i])), conv(Str2Num(value[i+1:])))                  return (conv(Str2Num(value[:i])), conv(Str2Num(value[i+1:])))
515    
516          assert(False) # shouldn't get here          assert False  # shouldn't get here
517          return (0,)          return (0,)
518                            
519    
# Line 443  class ClassTable(wxPyGridTableBase): Line 529  class ClassTable(wxPyGridTableBase):
529          typeName -- unused, but needed to overload wxPyGridTableBase          typeName -- unused, but needed to overload wxPyGridTableBase
530          """          """
531    
532          assert(col >= 0 and col < self.GetNumberCols())          assert col >= 0 and col < self.GetNumberCols()
533          assert(row >= 0 and row < self.GetNumberRows())          assert row >= 0 and row < self.GetNumberRows()
534    
535          group = self.tdata[row]          group = self.tdata[row]
536    
# Line 489  class ClassTable(wxPyGridTableBase): Line 575  class ClassTable(wxPyGridTableBase):
575                              changed = True                              changed = True
576                          ngroup.SetRange(dataInfo[0], dataInfo[1])                          ngroup.SetRange(dataInfo[0], dataInfo[1])
577                      else:                      else:
578                          assert(False)                          assert False
579                          pass                          pass
580    
581                      if changed:                      if changed:
582                          ngroup.SetLabel(group.GetLabel())                          ngroup.SetLabel(group.GetLabel())
583                          self.SetClassGroup(row, ngroup)                          self.SetClassGroup(row, ngroup)
584          else:          else:
585              assert(False) # shouldn't be here              assert False # shouldn't be here
586              pass              pass
587    
588          if mod:          if mod:
# Line 551  class ClassTable(wxPyGridTableBase): Line 637  class ClassTable(wxPyGridTableBase):
637          The table is considered modified if any rows are removed.          The table is considered modified if any rows are removed.
638          """          """
639    
640          assert(pos >= 0)          assert pos >= 0
641          old_len = len(self.tdata)          old_len = len(self.tdata)
642          for row in range(pos, pos - numRows, -1):          for row in range(pos, pos - numRows, -1):
643              group = self.GetClassGroup(row)              group = self.GetClassGroup(row)
# Line 571  class ClassTable(wxPyGridTableBase): Line 657  class ClassTable(wxPyGridTableBase):
657          old_len = len(self.tdata)          old_len = len(self.tdata)
658          for i in range(numRows):          for i in range(numRows):
659              np = ClassGroupSingleton()              np = ClassGroupSingleton()
660              self.__SetRow(-1, np)              self.__SetRow(None, np)
661    
662          if self.IsModified():          if self.IsModified():
663              self.__NotifyRowChanges(old_len, len(self.tdata))              self.__NotifyRowChanges(old_len, len(self.tdata))
664    
665    
666  class Classifier(NonModalDialog):  class Classifier(NonModalDialog):
667        
668      def __init__(self, parent, interactor, name, layer):      def __init__(self, parent, name, layer, group = None):
669          NonModalDialog.__init__(self, parent, interactor, name,          NonModalDialog.__init__(self, parent, name,
670                                  _("Classifier: %s") % layer.Title())                                  _("Classifier: %s") % layer.Title())
671    
672          panel = wxPanel(self, -1)          panel = wxPanel(self, -1, size=(100, 100))
673    
674          self.layer = layer          self.layer = layer
675    
# Line 592  class Classifier(NonModalDialog): Line 678  class Classifier(NonModalDialog):
678          fieldType = self.originalClass.GetFieldType()          fieldType = self.originalClass.GetFieldType()
679    
680          topBox = wxBoxSizer(wxVERTICAL)          topBox = wxBoxSizer(wxVERTICAL)
681            panelBox = wxBoxSizer(wxVERTICAL)
682    
683          #topBox.Add(wxStaticText(panel, -1, _("Layer: %s") % layer.Title()),          #panelBox.Add(wxStaticText(panel, -1, _("Layer: %s") % layer.Title()),
684              #0, wxALIGN_LEFT | wxALL, 4)              #0, wxALIGN_LEFT | wxALL, 4)
685          topBox.Add(wxStaticText(panel, -1,          panelBox.Add(wxStaticText(panel, -1,
686                                  _("Layer Type: %s") % layer.ShapeType()),                                  _("Layer Type: %s") % layer.ShapeType()),
687              0, wxALIGN_LEFT | wxALL, 4)              0, wxALIGN_LEFT | wxALL, 4)
688    
# Line 628  class Classifier(NonModalDialog): Line 715  class Classifier(NonModalDialog):
715          ###########          ###########
716    
717          self.fieldTypeText = wxStaticText(panel, -1, "")          self.fieldTypeText = wxStaticText(panel, -1, "")
718          topBox.Add(self.fieldTypeText, 0, wxGROW | wxALIGN_LEFT | wxALL, 4)          panelBox.Add(self.fieldTypeText, 0,
719                         wxGROW | wxALIGN_LEFT | wxALL | wxADJUST_MINSIZE, 4)
720    
721          propertyBox = wxBoxSizer(wxHORIZONTAL)          propertyBox = wxBoxSizer(wxHORIZONTAL)
722          propertyBox.Add(wxStaticText(panel, -1, _("Field: ")),          propertyBox.Add(wxStaticText(panel, -1, _("Field: ")),
# Line 636  class Classifier(NonModalDialog): Line 724  class Classifier(NonModalDialog):
724          propertyBox.Add(self.fields, 1, wxGROW|wxALL, 4)          propertyBox.Add(self.fields, 1, wxGROW|wxALL, 4)
725          EVT_COMBOBOX(self, ID_PROPERTY_SELECT, self._OnFieldSelect)          EVT_COMBOBOX(self, ID_PROPERTY_SELECT, self._OnFieldSelect)
726    
727          topBox.Add(propertyBox, 0, wxGROW, 4)          panelBox.Add(propertyBox, 0, wxGROW, 4)
728    
729    
         ###########  
730          #          #
731          # Classification data table          # Control Box
732          #          #
   
733          controlBox = wxBoxSizer(wxHORIZONTAL)          controlBox = wxBoxSizer(wxHORIZONTAL)
734    
         self.classGrid = ClassGrid(self)  
         self.__SetGridTable(self.__cur_field)  
   
         controlBox.Add(self.classGrid, 1, wxGROW, 0)  
735    
736          ###########          ###########
737          #          #
# Line 662  class Classifier(NonModalDialog): Line 745  class Classifier(NonModalDialog):
745          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
746          self.controlButtons.append(button)          self.controlButtons.append(button)
747    
748          #button = wxButton(panel, ID_CLASSIFY_GENRANGE, _("Generate Ranges"))          button = wxButton(panel, ID_CLASSIFY_EDITPROPS, _("Edit Properties"))
749          #controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
750          #self.controlButtons.append(button)          self.controlButtons.append(button)
751    
752            button = wxButton(panel, ID_CLASSIFY_GENCLASS, _("Generate Class"))
753            controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
754            self.controlButtons.append(button)
755    
756          button = wxButton(panel, ID_CLASSIFY_MOVEUP, _("Move Up"))          button = wxButton(panel, ID_CLASSIFY_MOVEUP, _("Move Up"))
757          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
# Line 680  class Classifier(NonModalDialog): Line 767  class Classifier(NonModalDialog):
767          controlButtonBox.Add(button, 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)          controlButtonBox.Add(button, 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)
768          self.controlButtons.append(button)          self.controlButtons.append(button)
769    
770    
771            ###########
772            #
773            # Classification data table
774            #
775    
776            self.classGrid = ClassGrid(panel, self)
777            #self.__SetGridTable(self.__cur_field, group)
778            #self.fields.SetSelection(self.__cur_field)
779    
780            # calling __SelectField after creating the classGrid fills in the
781            # grid with the correct information
782            #print "2------------------"
783            self.fields.SetSelection(self.__cur_field)
784            self.__SelectField(self.__cur_field, group = group)
785    
786            #self.classGrid.SelectGroup(group)
787    
788            controlBox.Add(self.classGrid, 1, wxGROW, 0)
789    
790    
791    
792          controlBox.Add(controlButtonBox, 0, wxGROW, 10)          controlBox.Add(controlButtonBox, 0, wxGROW, 10)
793          topBox.Add(controlBox, 0, wxGROW, 10)          panelBox.Add(controlBox, 1, wxGROW, 10)
794    
795          EVT_BUTTON(self, ID_CLASSIFY_ADD, self._OnAdd)          EVT_BUTTON(self, ID_CLASSIFY_ADD, self._OnAdd)
796            EVT_BUTTON(self, ID_CLASSIFY_EDITPROPS, self._OnEditGroupProperties)
797          EVT_BUTTON(self, ID_CLASSIFY_REMOVE, self._OnRemove)          EVT_BUTTON(self, ID_CLASSIFY_REMOVE, self._OnRemove)
798          EVT_BUTTON(self, ID_CLASSIFY_GENRANGE, self._OnGenRange)          EVT_BUTTON(self, ID_CLASSIFY_GENCLASS, self._OnGenClass)
799          EVT_BUTTON(self, ID_CLASSIFY_MOVEUP, self._OnMoveUp)          EVT_BUTTON(self, ID_CLASSIFY_MOVEUP, self._OnMoveUp)
800          EVT_BUTTON(self, ID_CLASSIFY_MOVEDOWN, self._OnMoveDown)          EVT_BUTTON(self, ID_CLASSIFY_MOVEDOWN, self._OnMoveDown)
801    
# Line 700  class Classifier(NonModalDialog): Line 810  class Classifier(NonModalDialog):
810          buttonBox.Add(60, 20, 0, wxALL, 4)          buttonBox.Add(60, 20, 0, wxALL, 4)
811          buttonBox.Add(wxButton(panel, ID_CLASSIFY_CANCEL, _("Cancel")),          buttonBox.Add(wxButton(panel, ID_CLASSIFY_CANCEL, _("Cancel")),
812                        0, wxALL, 4)                        0, wxALL, 4)
813          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 0)          panelBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 0)
814    
815          EVT_BUTTON(self, ID_CLASSIFY_OK, self._OnOK)          EVT_BUTTON(self, ID_CLASSIFY_OK, self._OnOK)
816          EVT_BUTTON(self, ID_CLASSIFY_APPLY, self._OnApply)          EVT_BUTTON(self, ID_CLASSIFY_APPLY, self._OnApply)
# Line 708  class Classifier(NonModalDialog): Line 818  class Classifier(NonModalDialog):
818    
819          ###########          ###########
820    
         self.fields.SetSelection(self.__cur_field)  
         self.__SelectField(self.__cur_field)  
821    
822          panel.SetAutoLayout(True)          panel.SetAutoLayout(True)
823          panel.SetSizer(topBox)          panel.SetSizer(panelBox)
824            panelBox.SetSizeHints(panel)
         topBox.SetSizeHints(panel)  
         topBox.Fit(panel)  
825    
826            topBox.Add(panel, 1, wxGROW, 0)
827            panelBox.SetSizeHints(self)
828          self.SetAutoLayout(True)          self.SetAutoLayout(True)
829          self.Fit()          self.SetSizer(topBox)
830    
831            #print "1------------------"
832            #self.Fit()
833            ######################
834    
835            self.haveApplied = False
836    
837        def EditGroupProperties(self, row):
838            table = self.classGrid.GetTable()
839            prop = table.GetValueAsCustom(row, COL_SYMBOL, None)
840    
841            # get a new ClassGroupProperties object and copy the
842            # values over to our current object
843            propDlg = SelectPropertiesDialog(NULL, prop, self.layer.ShapeType())
844            if propDlg.ShowModal() == wxID_OK:
845                new_prop = propDlg.GetClassGroupProperties()
846                table.SetValueAsCustom(row, COL_SYMBOL, None, new_prop)
847            propDlg.Destroy()
848            
849    
850      def __BuildClassification(self, fieldIndex):      def __BuildClassification(self, fieldIndex):
851    
852          numRows = self.classGrid.GetNumberRows()          numRows = self.classGrid.GetNumberRows()
853          assert(numRows > 0) # there should always be a default row          assert numRows > 0  # there should always be a default row
854    
855          clazz = Classification()          clazz = Classification()
856          if fieldIndex == 0:          if fieldIndex == 0:
# Line 746  class Classifier(NonModalDialog): Line 872  class Classifier(NonModalDialog):
872    
873          return clazz          return clazz
874    
875      def __SetGridTable(self, fieldIndex):      def __SetGridTable(self, fieldIndex, group = None):
876    
877          clazz = self.fields.GetClientData(fieldIndex)          clazz = self.fields.GetClientData(fieldIndex)
878    
# Line 761  class Classifier(NonModalDialog): Line 887  class Classifier(NonModalDialog):
887              fieldType = self.layer.GetFieldType(fieldName)              fieldType = self.layer.GetFieldType(fieldName)
888              clazz.SetFieldType(fieldType)              clazz.SetFieldType(fieldType)
889                                    
890          self.classGrid.CreateTable(clazz, self.layer.ShapeType())          #print "6------------------"
891            self.classGrid.CreateTable(clazz, self.layer.ShapeType(), group)
892            #print "7------------------"
893    
894    
895    
# Line 774  class Classifier(NonModalDialog): Line 902  class Classifier(NonModalDialog):
902          fieldName = self.fields.GetString(fieldIndex)          fieldName = self.fields.GetString(fieldIndex)
903          fieldType = self.layer.GetFieldType(fieldName)          fieldType = self.layer.GetFieldType(fieldName)
904    
905          assert(Classifier.type2string.has_key(fieldType))          assert Classifier.type2string.has_key(fieldType)
906    
907          text = Classifier.type2string[fieldType]          text = Classifier.type2string[fieldType]
908    
909          self.fieldTypeText.SetLabel(_("Field Type: %s") % text)          self.fieldTypeText.SetLabel(_("Field Type: %s") % text)
910    
911      def __SelectField(self, newIndex, oldIndex = -1):      def __SelectField(self, newIndex, oldIndex = -1, group = None):
912            """This method assumes that the current selection for the
913            combo has already been set by a call to SetSelection().
914            """
915    
916            #print "3------------------"
917    
918          assert(oldIndex >= -1)          assert oldIndex >= -1
919    
920          if oldIndex != -1:          if oldIndex != -1:
921              clazz = self.__BuildClassification(oldIndex)              clazz = self.__BuildClassification(oldIndex)
922              self.fields.SetClientData(oldIndex, clazz)              self.fields.SetClientData(oldIndex, clazz)
923    
924          self.__SetGridTable(newIndex)          #print "4------------------"
925            self.__SetGridTable(newIndex, group)
926            #print "5------------------"
927    
928          enabled = newIndex != 0          enabled = newIndex != 0
929    
# Line 798  class Classifier(NonModalDialog): Line 933  class Classifier(NonModalDialog):
933          self.__SetFieldTypeText(newIndex)          self.__SetFieldTypeText(newIndex)
934    
935    
936        def _OnEditGroupProperties(self, event):
937            sel = self.classGrid.GetCurrentSelection()
938    
939            if len(sel) == 1:
940                self.EditGroupProperties(sel[0])
941    
942      def _OnFieldSelect(self, event):      def _OnFieldSelect(self, event):
943          index = self.fields.GetSelection()          index = self.fields.GetSelection()
944          self.__SelectField(index, self.__cur_field)          self.__SelectField(index, self.__cur_field)
# Line 819  class Classifier(NonModalDialog): Line 960  class Classifier(NonModalDialog):
960    
961          self.layer.SetClassification(clazz)          self.layer.SetClassification(clazz)
962    
963            self.haveApplied = True
964    
965      def _OnOK(self, event):      def _OnOK(self, event):
966          self._OnApply(event)          self._OnApply(event)
967          self.OnClose(event)          self.OnClose(event)
968    
969      def _OnCancel(self, event):      def _OnCancel(self, event):
970          """The layer's current classification stays the same."""          """The layer's current classification stays the same."""
971          self.layer.SetClassification(self.originalClass)          if self.haveApplied:
972                self.layer.SetClassification(self.originalClass)
973    
974          self.OnClose(event)          self.OnClose(event)
975    
976      def _OnAdd(self, event):      def _OnAdd(self, event):
# Line 834  class Classifier(NonModalDialog): Line 979  class Classifier(NonModalDialog):
979      def _OnRemove(self, event):      def _OnRemove(self, event):
980          self.classGrid.DeleteSelectedRows()          self.classGrid.DeleteSelectedRows()
981    
982      def _OnGenRange(self, event):      def _OnGenClass(self, event):
983          print "Classifier._OnGenRange()"  
984            genDlg = ClassGenDialog(self,
985                                    self.layer.table,
986                                    self.fields.GetString(self.__cur_field))
987    
988            if genDlg.ShowModal() == wxID_OK:
989                clazz = genDlg.GetClassification()
990                self.fields.SetClientData(self.__cur_field, clazz)
991                self.classGrid.GetTable().SetClassification(clazz)
992            genDlg.Destroy()
993    
994      def _OnMoveUp(self, event):      def _OnMoveUp(self, event):
995          sel = self.classGrid.GetCurrentSelection()          sel = self.classGrid.GetCurrentSelection()
996    
997            #print "sel: ", sel
998    
999          if len(sel) == 1:          if len(sel) == 1:
1000              i = sel[0]              i = sel[0]
1001              if i > 1:              if i > 1:
# Line 850  class Classifier(NonModalDialog): Line 1006  class Classifier(NonModalDialog):
1006                  table.SetClassGroup(i, x)                  table.SetClassGroup(i, x)
1007                  self.classGrid.ClearSelection()                  self.classGrid.ClearSelection()
1008                  self.classGrid.SelectRow(i - 1)                  self.classGrid.SelectRow(i - 1)
1009                    self.classGrid.MakeCellVisible(i - 1, 0)
1010    
1011      def _OnMoveDown(self, event):      def _OnMoveDown(self, event):
1012          sel = self.classGrid.GetCurrentSelection()          sel = self.classGrid.GetCurrentSelection()
# Line 864  class Classifier(NonModalDialog): Line 1021  class Classifier(NonModalDialog):
1021                  table.SetClassGroup(i + 1, x)                  table.SetClassGroup(i + 1, x)
1022                  self.classGrid.ClearSelection()                  self.classGrid.ClearSelection()
1023                  self.classGrid.SelectRow(i + 1)                  self.classGrid.SelectRow(i + 1)
1024                    self.classGrid.MakeCellVisible(i + 1, 0)
1025    
1026    
1027  ID_SELPROP_OK = 4001  ID_SELPROP_OK = 4001
# Line 891  class SelectPropertiesDialog(wxDialog): Line 1049  class SelectPropertiesDialog(wxDialog):
1049          previewBox = wxBoxSizer(wxVERTICAL)          previewBox = wxBoxSizer(wxVERTICAL)
1050          previewBox.Add(wxStaticText(self, -1, _("Preview:")),          previewBox.Add(wxStaticText(self, -1, _("Preview:")),
1051              0, wxALIGN_LEFT | wxALL, 4)              0, wxALIGN_LEFT | wxALL, 4)
1052          self.previewer = ClassDataPreviewer(None, self.prop, shapeType,          self.previewWin = ClassDataPreviewWindow(None, self.prop, shapeType,
1053                                              self, ID_SELPROP_PREVIEW, (40, 40))                                              self, ID_SELPROP_PREVIEW, (40, 40))
1054          previewBox.Add(self.previewer, 1, wxGROW, 15)          previewBox.Add(self.previewWin, 1, wxGROW, 15)
1055    
1056          itemBox.Add(previewBox, 1, wxALIGN_LEFT | wxALL | wxGROW, 0)          itemBox.Add(previewBox, 1, wxALIGN_LEFT | wxALL | wxGROW, 0)
1057    
# Line 971  class SelectPropertiesDialog(wxDialog): Line 1129  class SelectPropertiesDialog(wxDialog):
1129    
1130      def _OnSpin(self, event):      def _OnSpin(self, event):
1131          self.prop.SetLineWidth(self.spinCtrl.GetValue())          self.prop.SetLineWidth(self.spinCtrl.GetValue())
1132          self.previewer.Refresh()          self.previewWin.Refresh()
1133    
1134      def __GetColor(self, cur):      def __GetColor(self, cur):
1135          dialog = wxColourDialog(self)          dialog = wxColourDialog(self)
1136          dialog.GetColourData().SetColour(Color2wxColour(cur))          if cur is not Color.Transparent:
1137                dialog.GetColourData().SetColour(Color2wxColour(cur))
1138    
1139          ret = None          ret = None
1140          if dialog.ShowModal() == wxID_OK:          if dialog.ShowModal() == wxID_OK:
1141              ret = wxColour2Color(dialog.GetColourData().GetColour())              ret = wxColour2Color(dialog.GetColourData().GetColour())
# Line 988  class SelectPropertiesDialog(wxDialog): Line 1148  class SelectPropertiesDialog(wxDialog):
1148          clr = self.__GetColor(self.prop.GetLineColor())          clr = self.__GetColor(self.prop.GetLineColor())
1149          if clr is not None:          if clr is not None:
1150              self.prop.SetLineColor(clr)              self.prop.SetLineColor(clr)
1151          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer
1152    
1153      def _OnChangeLineColorTrans(self, event):      def _OnChangeLineColorTrans(self, event):
1154          self.prop.SetLineColor(Color.None)          self.prop.SetLineColor(Color.Transparent)
1155          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer
1156                    
1157      def _OnChangeFillColor(self, event):      def _OnChangeFillColor(self, event):
1158          clr = self.__GetColor(self.prop.GetFill())          clr = self.__GetColor(self.prop.GetFill())
1159          if clr is not None:          if clr is not None:
1160              self.prop.SetFill(clr)              self.prop.SetFill(clr)
1161          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer
1162    
1163      def _OnChangeFillColorTrans(self, event):      def _OnChangeFillColorTrans(self, event):
1164          self.prop.SetFill(Color.None)          self.prop.SetFill(Color.Transparent)
1165          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer
1166    
1167      def GetClassGroupProperties(self):      def GetClassGroupProperties(self):
1168          return self.prop          return self.prop
1169    
1170    
1171  class ClassDataPreviewer(wxWindow):  class ClassDataPreviewWindow(wxWindow):
1172    
1173      def __init__(self, rect, prop, shapeType,      def __init__(self, rect, prop, shapeType,
1174                         parent = None, id = -1, size = wxDefaultSize):                         parent = None, id = -1, size = wxDefaultSize):
1175          if parent is not None:          if parent is not None:
1176              wxWindow.__init__(self, parent, id, size=size)              wxWindow.__init__(self, parent, id, (0, 0), size)
1177              EVT_PAINT(self, self._OnPaint)              EVT_PAINT(self, self._OnPaint)
1178    
1179          self.rect = rect          self.rect = rect
1180    
1181          self.prop = prop          self.prop = prop
1182          self.shapeType = shapeType          self.shapeType = shapeType
1183            self.previewer = ClassDataPreviewer()
1184    
1185      def _OnPaint(self, event):      def _OnPaint(self, event):
1186          dc = wxPaintDC(self)          dc = wxPaintDC(self)
# Line 1026  class ClassDataPreviewer(wxWindow): Line 1188  class ClassDataPreviewer(wxWindow):
1188          # XXX: this doesn't seem to be having an effect:          # XXX: this doesn't seem to be having an effect:
1189          dc.DestroyClippingRegion()          dc.DestroyClippingRegion()
1190    
1191          self.Draw(dc, None)          if self.rect is None:
1192                w, h = self.GetSize()
1193                rect = wxRect(0, 0, w, h)
1194            else:
1195                rect = self.rect
1196    
1197            self.previewer.Draw(dc, rect, self.prop, self.shapeType)
1198    
1199    class ClassDataPreviewer:
1200    
1201      def Draw(self, dc, rect, prop = None, shapeType = None):      def Draw(self, dc, rect, prop, shapeType):
1202    
1203          if prop is None: prop = self.prop          assert dc is not None
1204          if shapeType is None: shapeType = self.shapeType          assert isinstance(prop, ClassGroupProperties)
1205    
1206          if rect is None:          if rect is None:
1207              x = y = 0              x = 0
1208              w, h = self.GetClientSizeTuple()              y = 0
1209                w, h = dc.GetSize()
1210          else:          else:
1211              x = rect.GetX()              x = rect.GetX()
1212              y = rect.GetY()              y = rect.GetY()
# Line 1043  class ClassDataPreviewer(wxWindow): Line 1214  class ClassDataPreviewer(wxWindow):
1214              h = rect.GetHeight()              h = rect.GetHeight()
1215    
1216          stroke = prop.GetLineColor()          stroke = prop.GetLineColor()
1217          if stroke is Color.None:          if stroke is Color.Transparent:
1218              pen = wxTRANSPARENT_PEN              pen = wxTRANSPARENT_PEN
1219          else:          else:
1220              pen = wxPen(Color2wxColour(stroke),              pen = wxPen(Color2wxColour(stroke),
# Line 1051  class ClassDataPreviewer(wxWindow): Line 1222  class ClassDataPreviewer(wxWindow):
1222                          wxSOLID)                          wxSOLID)
1223    
1224          stroke = prop.GetFill()          stroke = prop.GetFill()
1225          if stroke is Color.None:          if stroke is Color.Transparent:
1226              brush = wxTRANSPARENT_BRUSH              brush = wxTRANSPARENT_BRUSH
1227          else:          else:
1228              brush = wxBrush(Color2wxColour(stroke), wxSOLID)              brush = wxBrush(Color2wxColour(stroke), wxSOLID)
# Line 1065  class ClassDataPreviewer(wxWindow): Line 1236  class ClassDataPreviewer(wxWindow):
1236                             wxPoint(x + w/2, y + h/4*3),                             wxPoint(x + w/2, y + h/4*3),
1237                             wxPoint(x + w, y)])                             wxPoint(x + w, y)])
1238    
1239          elif shapeType == SHAPETYPE_POINT or \          elif shapeType == SHAPETYPE_POINT:
              shapeType == SHAPETYPE_POLYGON:  
1240    
1241              dc.DrawCircle(x + w/2, y + h/2,              dc.DrawCircle(x + w/2, y + h/2,
1242                            (min(w, h) - prop.GetLineWidth())/2)                            (min(w, h) - prop.GetLineWidth())/2)
1243    
1244            elif shapeType == SHAPETYPE_POLYGON:
1245                dc.DrawRectangle(x, y, w, h)
1246    
1247  class ClassRenderer(wxPyGridCellRenderer):  class ClassRenderer(wxPyGridCellRenderer):
1248    
1249      def __init__(self, shapeType):      def __init__(self, shapeType):
1250          wxPyGridCellRenderer.__init__(self)          wxPyGridCellRenderer.__init__(self)
1251          self.previewer = ClassDataPreviewer(None, None, shapeType)          self.shapeType = shapeType
1252            self.previewer = ClassDataPreviewer()
1253    
1254      def Draw(self, grid, attr, dc, rect, row, col, isSelected):      def Draw(self, grid, attr, dc, rect, row, col, isSelected):
1255          data = grid.GetTable().GetClassGroup(row)          data = grid.GetTable().GetClassGroup(row)
# Line 1088  class ClassRenderer(wxPyGridCellRenderer Line 1262  class ClassRenderer(wxPyGridCellRenderer
1262                           rect.GetWidth(), rect.GetHeight())                           rect.GetWidth(), rect.GetHeight())
1263    
1264          if not isinstance(data, ClassGroupMap):          if not isinstance(data, ClassGroupMap):
1265              self.previewer.Draw(dc, rect, data.GetProperties())              self.previewer.Draw(dc, rect, data.GetProperties(), self.shapeType)
1266    
1267          if isSelected:          if isSelected:
1268              dc.SetPen(wxPen(wxColour(0 * 255, 0 * 255, 0 * 255),              dc.SetPen(wxPen(wxColour(0 * 255, 0 * 255, 0 * 255),

Legend:
Removed from v.509  
changed lines
  Added in v.611

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26