/[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 498 by jonathan, Mon Mar 10 11:03:22 2003 UTC revision 630 by jonathan, Wed Apr 9 10:10:06 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
35  ID_PROPERTY_SELECT = 4010  ID_PROPERTY_SELECT = 4010
36  ID_CLASS_TABLE = 40011  ID_CLASS_TABLE = 40011
37    
 ID_CLASSIFY_OK = 4001  
 ID_CLASSIFY_CANCEL = 4002  
 ID_CLASSIFY_ADD = 4003  
 ID_CLASSIFY_GENRANGE = 4004  
 ID_CLASSIFY_REMOVE = 4005  
 ID_CLASSIFY_MOVEUP = 4006  
 ID_CLASSIFY_MOVEDOWN = 4007  
 ID_CLASSIFY_APPLY = 4008  
38    
39  # table columns  # table columns
40  COL_SYMBOL = 0  COL_SYMBOL = 0
# Line 59  FIELD_NAME = 2 Line 53  FIELD_NAME = 2
53  import weakref  import weakref
54  class ClassGrid(wxGrid):  class ClassGrid(wxGrid):
55    
56      def __init__(self, parent):  
57        def __init__(self, parent, classifier):
58          """Constructor.          """Constructor.
59    
60          parent -- the parent window          parent -- the parent window
# Line 70  class ClassGrid(wxGrid): Line 65  class ClassGrid(wxGrid):
65    
66          #wxGrid.__init__(self, parent, ID_CLASS_TABLE, size = (340, 160))          #wxGrid.__init__(self, parent, ID_CLASS_TABLE, size = (340, 160))
67          wxGrid.__init__(self, parent, ID_CLASS_TABLE)          wxGrid.__init__(self, parent, ID_CLASS_TABLE)
68          #self.SetTable(ClassTable(fieldData, layer.ShapeType(), self), true)          #self.SetTable(ClassTable(fieldData, layer.ShapeType(), self), True)
69    
70            self.classifier = classifier
71    
72            self.currentSelection = []
73    
74          EVT_GRID_CELL_LEFT_DCLICK(self, self._OnCellDClick)          EVT_GRID_CELL_LEFT_DCLICK(self, self._OnCellDClick)
75          EVT_GRID_RANGE_SELECT(self, self._OnSelectedRange)          EVT_GRID_RANGE_SELECT(self, self._OnSelectedRange)
76          EVT_GRID_SELECT_CELL(self, self._OnSelectedCell)          EVT_GRID_SELECT_CELL(self, self._OnSelectedCell)
77            EVT_GRID_COL_SIZE(self, self._OnCellResize)
78            EVT_GRID_ROW_SIZE(self, self._OnCellResize)
79    
80          self.currentSelection = []      def CreateTable(self, clazz, shapeType, group = None):
   
     def CreateTable(self, clazz, shapeType):  
81    
82          assert(isinstance(clazz, Classification))          assert isinstance(clazz, Classification)
83    
         self.shapeType = shapeType  
84          table = self.GetTable()          table = self.GetTable()
85          if table is None:          if table is None:
86              self.SetTable(ClassTable(clazz, self.shapeType, self), true)              w = self.GetDefaultColSize() * 3 + self.GetDefaultRowLabelSize()
87          else:              h = self.GetDefaultRowSize() * 4 + self.GetDefaultColLabelSize()
88              table.Reset(clazz, self.shapeType)              self.SetDimensions(-1, -1, w, h)
89                self.SetSizeHints(w, h, -1, -1)
90                table = ClassTable(self)
91                self.SetTable(table, True)
92    
93    
94          self.SetSelectionMode(wxGrid.wxGridSelectRows)          self.SetSelectionMode(wxGrid.wxGridSelectRows)
95          self.ClearSelection()          self.ClearSelection()
96    
97            table.Reset(clazz, shapeType, group)
98    
99      def GetCurrentSelection(self):      def GetCurrentSelection(self):
100          """Return the currently highlighted rows as an increasing list          """Return the currently highlighted rows as an increasing list
101             of row numbers."""             of row numbers."""
# Line 99  class ClassGrid(wxGrid): Line 103  class ClassGrid(wxGrid):
103          sel.sort()          sel.sort()
104          return sel          return sel
105    
106        def GetSelectedRows(self):
107            return self.GetCurrentSelection()
108    
109      def SetCellRenderer(self, row, col):      def SetCellRenderer(self, row, col):
110          raise ValueError(_("Must not allow setting of renderer in ClassGrid!"))          raise ValueError(_("Must not allow setting of renderer in ClassGrid!"))
111    
# Line 165  class ClassGrid(wxGrid): Line 172  class ClassGrid(wxGrid):
172                  r = self.GetNumberRows() - 1                  r = self.GetNumberRows() - 1
173              self.SelectRow(r)              self.SelectRow(r)
174                    
175    
176        def SelectGroup(self, group, makeVisible = True):
177            if group is None: return
178    
179            assert isinstance(group, ClassGroup)
180    
181            table = self.GetTable()
182    
183            assert table is not None
184    
185            for i in range(table.GetNumberRows()):
186                g = table.GetClassGroup(i)
187                if g is group:
188                    self.SelectRow(i)
189                    if makeVisible:
190                        self.MakeCellVisible(i, 0)
191                    break
192    
193  #  #
194  # 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!
195  #  #
# Line 182  class ClassGrid(wxGrid): Line 207  class ClassGrid(wxGrid):
207          r = event.GetRow()          r = event.GetRow()
208          c = event.GetCol()          c = event.GetCol()
209          if c == COL_SYMBOL:          if c == COL_SYMBOL:
210              prop = self.GetTable().GetValueAsCustom(r, c, None)              self.classifier.EditGroupProperties(r)
             #prop = group.GetProperties()  
211    
             # 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()  
212    
213      #      #
214      # _OnSelectedRange() and _OnSelectedCell() were borrowed      # _OnSelectedRange() and _OnSelectedCell() were borrowed
# Line 219  class ClassGrid(wxGrid): Line 235  class ClassGrid(wxGrid):
235          #self.ConfigureForSelection()          #self.ConfigureForSelection()
236          event.Skip()          event.Skip()
237    
238        def _OnCellResize(self, event):
239            self.FitInside()
240    
241  class ClassTable(wxPyGridTableBase):  class ClassTable(wxPyGridTableBase):
242      """Represents the underlying data structure for the grid."""      """Represents the underlying data structure for the grid."""
243    
# Line 226  class ClassTable(wxPyGridTableBase): Line 245  class ClassTable(wxPyGridTableBase):
245    
246      __col_labels = [_("Symbol"), _("Value"), _("Label")]      __col_labels = [_("Symbol"), _("Value"), _("Label")]
247    
248      def __init__(self, clazz, shapeType, view = None):  
249        def __init__(self, view = None):
250        #def __init__(self, clazz, shapeType, view = None):
251          """Constructor.          """Constructor.
252    
253          shapeType -- the type of shape that the layer uses          shapeType -- the type of shape that the layer uses
# Line 237  class ClassTable(wxPyGridTableBase): Line 258  class ClassTable(wxPyGridTableBase):
258          wxPyGridTableBase.__init__(self)          wxPyGridTableBase.__init__(self)
259    
260          self.SetView(view)          self.SetView(view)
261          self.tdata = []          self.clazz = None
262    
263          self.Reset(clazz, shapeType)          #self.Reset(clazz, shapeType)
264    
265      def Reset(self, clazz, shapeType):      def Reset(self, clazz, shapeType, group = None):
266          """Reset the table with the given data.          """Reset the table with the given data.
267    
268          This is necessary because wxWindows does not allow a grid's          This is necessary because wxWindows does not allow a grid's
# Line 255  class ClassTable(wxPyGridTableBase): Line 276  class ClassTable(wxPyGridTableBase):
276          shapeType -- the type of shape that the layer uses          shapeType -- the type of shape that the layer uses
277          """          """
278    
279          assert(isinstance(clazz, Classification))          assert isinstance(clazz, Classification)
280    
281          self.GetView().BeginBatch()          self.GetView().BeginBatch()
282    
283          self.fieldType = clazz.GetFieldType()          self.fieldType = clazz.GetFieldType()
284          self.shapeType = shapeType          self.shapeType = shapeType
285    
286          old_len = len(self.tdata)          self.SetClassification(clazz, group)
287            self.__Modified(-1)
288    
289            self.GetView().EndBatch()
290            self.GetView().FitInside()
291    
292        def GetClassification(self):
293            return self.clazz
294    
295          self.tdata = []      def SetClassification(self, clazz, group = None):
296    
297            self.GetView().BeginBatch()
298    
299            old_len = self.GetNumberRows()
300    
301          #          #
302          # copy the data out of the classification and into our          # copy the data out of the classification and into our
303          # array          # array
304          #          #
305          for p in clazz:          row = -1
306              np = copy.deepcopy(p)  #       for g in clazz:
307              self.__SetRow(-1, np)  #           ng = copy.deepcopy(g)
308    #           self.__SetRow(None, ng)
309    #           if g is group:
310    #               row = self.GetNumberRows() - 1
311    #               #print "selecting row..."
312    
313    
314            #self.clazz = copy.deepcopy(clazz)
315            self.clazz = clazz
316    
317          self.__Modified(-1)          self.__NotifyRowChanges(old_len, self.GetNumberRows())
318    
319          self.__NotifyRowChanges(old_len, len(self.tdata))          if row > -1:
320                self.GetView().ClearSelection()
321                self.GetView().SelectRow(row)
322                self.GetView().MakeCellVisible(row, 0)
323    
324            self.__Modified()
325    
         view = self.GetView()  
         w = view.GetDefaultColSize() * 3 + view.GetDefaultRowLabelSize()  
         h = view.GetDefaultRowSize() * 4 + view.GetDefaultColLabelSize()  
         view.SetDimensions(-1, -1, w, h)  
         view.SetSizeHints(w, h, -1, -1)  
               
326          self.GetView().EndBatch()          self.GetView().EndBatch()
327            self.GetView().FitInside()
328    
329      def __NotifyRowChanges(self, curRows, newRows):      def __NotifyRowChanges(self, curRows, newRows):
330          #          #
# Line 297  class ClassTable(wxPyGridTableBase): Line 336  class ClassTable(wxPyGridTableBase):
336                          wxGRIDTABLE_NOTIFY_ROWS_APPENDED,                          wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
337                          newRows - curRows)    # how many                          newRows - curRows)    # how many
338              self.GetView().ProcessTableMessage(msg)              self.GetView().ProcessTableMessage(msg)
339                self.GetView().FitInside()
340          elif newRows < curRows:          elif newRows < curRows:
341              msg = wxGridTableMessage(self,              msg = wxGridTableMessage(self,
342                          wxGRIDTABLE_NOTIFY_ROWS_DELETED,                          wxGRIDTABLE_NOTIFY_ROWS_DELETED,
343                          curRows - newRows,    # position                          curRows,              # position
344                          curRows - newRows)    # how many                          curRows - newRows)    # how many
345              self.GetView().ProcessTableMessage(msg)              self.GetView().ProcessTableMessage(msg)
346                self.GetView().FitInside()
347    
348    
349      def __SetRow(self, row, group):      def __SetRow(self, row, group):
350          """Set a row's data to that of the group.          """Set a row's data to that of the group.
351    
352          The table is considered modified after this operation.          The table is considered modified after this operation.
353    
354          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
355                 then group is appended to the end.                 if row is >= GetNumberRows() or None 'group' is append to
356                        the end of the table.
357                   otherwise 'group' replaces row 'row'
358          """          """
359    
360          # either append or replace          # either append or replace
361          if row == -1 or row >= self.GetNumberRows():          if row is None or row >= self.GetNumberRows():
362              self.tdata.append(group)              self.clazz.AppendGroup(group)
363            elif row < 0:
364                self.clazz.InsertGroup(0, group)
365          else:          else:
366              self.tdata[row] = group              if row == 0:
367                    self.clazz.SetDefaultGroup(group)
368                else:
369                    self.clazz.ReplaceGroup(row - 1, group)
370    
371          self.__Modified()          self.__Modified()
372    
# Line 328  class ClassTable(wxPyGridTableBase): Line 377  class ClassTable(wxPyGridTableBase):
377      def GetRowLabelValue(self, row):      def GetRowLabelValue(self, row):
378          """Return the label for the given row."""          """Return the label for the given row."""
379    
380          group = self.tdata[row]          if row == 0:
381          if isinstance(group, ClassGroupDefault):   return _("Default")              return _("Default")
382          if isinstance(group, ClassGroupSingleton): return _("Singleton")          else:
383          if isinstance(group, ClassGroupRange):     return _("Range")              group = self.clazz.GetGroup(row - 1)
384          if isinstance(group, ClassGroupMap):       return _("Map")              if isinstance(group, ClassGroupDefault):   return _("Default")
385                if isinstance(group, ClassGroupSingleton): return _("Singleton")
386                if isinstance(group, ClassGroupRange):     return _("Range")
387                if isinstance(group, ClassGroupMap):       return _("Map")
388    
389          assert(False) # shouldn't get here          assert False # shouldn't get here
390          return _("")          return _("")
391    
392      def GetNumberRows(self):      def GetNumberRows(self):
393          """Return the number of rows."""          """Return the number of rows."""
394          return len(self.tdata)          if self.clazz is None:
395                return 0
396    
397            return self.clazz.GetNumGroups() + 1 # +1 for default group
398    
399      def GetNumberCols(self):      def GetNumberCols(self):
400          """Return the number of columns."""          """Return the number of columns."""
# Line 370  class ClassTable(wxPyGridTableBase): Line 425  class ClassTable(wxPyGridTableBase):
425          typeName -- unused, but needed to overload wxPyGridTableBase          typeName -- unused, but needed to overload wxPyGridTableBase
426          """          """
427    
428          group = self.tdata[row]          if row == 0:
429                group = self.clazz.GetDefaultGroup()
430            else:
431                group = self.clazz.GetGroup(row - 1)
432    
433    
434          if col == COL_SYMBOL:          if col == COL_SYMBOL:
435              return group.GetProperties()              return group.GetProperties()
# Line 379  class ClassTable(wxPyGridTableBase): Line 438  class ClassTable(wxPyGridTableBase):
438              return group.GetLabel()              return group.GetLabel()
439    
440          # col must be COL_VALUE          # col must be COL_VALUE
441          assert(col == COL_VALUE)          assert col == COL_VALUE
442    
443          if isinstance(group, ClassGroupDefault):          if isinstance(group, ClassGroupDefault):
444              return _("DEFAULT")              return _("DEFAULT")
# Line 403  class ClassTable(wxPyGridTableBase): Line 462  class ClassTable(wxPyGridTableBase):
462    
463          if type == FIELDTYPE_STRING:          if type == FIELDTYPE_STRING:
464              return (value,)              return (value,)
465          elif type == FIELDTYPE_INT or type == FIELDTYPE_DOUBLE:          elif type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):
466    
467              if type == FIELDTYPE_INT:              if type == FIELDTYPE_INT:
468                  conv = lambda p: int(float(p))                  conv = lambda p: int(float(p))
# Line 428  class ClassTable(wxPyGridTableBase): Line 487  class ClassTable(wxPyGridTableBase):
487    
488                  return (conv(Str2Num(value[:i])), conv(Str2Num(value[i+1:])))                  return (conv(Str2Num(value[:i])), conv(Str2Num(value[i+1:])))
489    
490          assert(False) # shouldn't get here          assert False  # shouldn't get here
491          return (0,)          return (0,)
492                            
493    
# Line 444  class ClassTable(wxPyGridTableBase): Line 503  class ClassTable(wxPyGridTableBase):
503          typeName -- unused, but needed to overload wxPyGridTableBase          typeName -- unused, but needed to overload wxPyGridTableBase
504          """          """
505    
506          assert(col >= 0 and col < self.GetNumberCols())          assert col >= 0 and col < self.GetNumberCols()
507          assert(row >= 0 and row < self.GetNumberRows())          assert row >= 0 and row < self.GetNumberRows()
508    
509          group = self.tdata[row]          if row == 0:
510                group = self.clazz.GetDefaultGroup()
511            else:
512                group = self.clazz.GetGroup(row - 1)
513    
514          mod = True # assume the data will change          mod = True # assume the data will change
515    
# Line 490  class ClassTable(wxPyGridTableBase): Line 552  class ClassTable(wxPyGridTableBase):
552                              changed = True                              changed = True
553                          ngroup.SetRange(dataInfo[0], dataInfo[1])                          ngroup.SetRange(dataInfo[0], dataInfo[1])
554                      else:                      else:
555                          assert(False)                          assert False
556                          pass                          pass
557    
558                      if changed:                      if changed:
559                          ngroup.SetLabel(group.GetLabel())                          ngroup.SetLabel(group.GetLabel())
560                          self.SetClassGroup(row, ngroup)                          self.SetClassGroup(row, ngroup)
561          else:          else:
562              assert(False) # shouldn't be here              assert False # shouldn't be here
563              pass              pass
564    
565          if mod:          if mod:
# Line 521  class ClassTable(wxPyGridTableBase): Line 583  class ClassTable(wxPyGridTableBase):
583      def GetClassGroup(self, row):      def GetClassGroup(self, row):
584          """Return the ClassGroup object representing row 'row'."""          """Return the ClassGroup object representing row 'row'."""
585    
586          return self.tdata[row] # self.GetValueAsCustom(row, COL_SYMBOL, None)          #return self.GetValueAsCustom(row, COL_SYMBOL, None)
587            if row == 0:
588                return self.clazz.GetDefaultGroup()
589            else:
590                return self.clazz.GetGroup(row - 1)
591    
592      def SetClassGroup(self, row, group):      def SetClassGroup(self, row, group):
593          self.__SetRow(row, group)          self.__SetRow(row, group)
# Line 552  class ClassTable(wxPyGridTableBase): Line 618  class ClassTable(wxPyGridTableBase):
618          The table is considered modified if any rows are removed.          The table is considered modified if any rows are removed.
619          """          """
620    
621          assert(pos >= 0)          assert pos >= 0
622          old_len = len(self.tdata)          old_len = self.GetNumberRows()
623          for row in range(pos, pos - numRows, -1):          for row in range(pos, pos - numRows, -1):
624              group = self.GetClassGroup(row)              group = self.GetClassGroup(row)
625              if not isinstance(group, ClassGroupDefault):              if row != 0:
626                  self.tdata.pop(row)                  self.clazz.RemoveGroup(row - 1)
627                  self.__Modified()                  self.__Modified()
628            
629          if self.IsModified():          if self.IsModified():
630              self.__NotifyRowChanges(old_len, len(self.tdata))              self.__NotifyRowChanges(old_len, self.GetNumberRows())
631    
632      def AppendRows(self, numRows = 1):      def AppendRows(self, numRows = 1):
633          """Append 'numRows' empty rows to the end of the table.          """Append 'numRows' empty rows to the end of the table.
# Line 569  class ClassTable(wxPyGridTableBase): Line 635  class ClassTable(wxPyGridTableBase):
635          The table is considered modified if any rows are appended.          The table is considered modified if any rows are appended.
636          """          """
637    
638          old_len = len(self.tdata)          old_len = self.GetNumberRows()
639          for i in range(numRows):          for i in range(numRows):
640              np = ClassGroupSingleton()              np = ClassGroupSingleton()
641              self.__SetRow(-1, np)              self.__SetRow(None, np)
642    
643          if self.IsModified():          if self.IsModified():
644              self.__NotifyRowChanges(old_len, len(self.tdata))              self.__NotifyRowChanges(old_len, self.GetNumberRows())
645    
646    
647    ID_CLASSIFY_OK = 4001
648    ID_CLASSIFY_CANCEL = 4002
649    ID_CLASSIFY_ADD = 4003
650    ID_CLASSIFY_GENCLASS = 4004
651    ID_CLASSIFY_REMOVE = 4005
652    ID_CLASSIFY_MOVEUP = 4006
653    ID_CLASSIFY_MOVEDOWN = 4007
654    ID_CLASSIFY_APPLY = 4008
655    ID_CLASSIFY_EDITPROPS = 4009
656    ID_CLASSIFY_CLOSE = 4010
657    
658    BTN_ADD = 0
659    BTN_EDIT = 1
660    BTN_GEN = 2
661    BTN_UP = 3
662    BTN_DOWN = 4
663    BTN_RM = 5
664    
665  class Classifier(NonModalDialog):  class Classifier(NonModalDialog):
666        
667      def __init__(self, parent, interactor, name, layer):      type2string = {None:             _("None"),
668          NonModalDialog.__init__(self, parent, interactor, name,                     FIELDTYPE_STRING: _("Text"),
669                       FIELDTYPE_INT:    _("Integer"),
670                       FIELDTYPE_DOUBLE: _("Decimal")}
671    
672        def __init__(self, parent, name, layer, group = None):
673            NonModalDialog.__init__(self, parent, name,
674                                  _("Classifier: %s") % layer.Title())                                  _("Classifier: %s") % layer.Title())
675    
676            panel = wxPanel(self, -1, size=(100, 100))
677    
678          self.layer = layer          self.layer = layer
679    
680          self.originalClass = self.layer.GetClassification()          self.originalClass = self.layer.GetClassification()
681          field = self.originalClass.GetField()          field = self.originalClass.GetField()
682          fieldType = self.originalClass.GetFieldType()          fieldType = self.originalClass.GetFieldType()
683    
684            self.genDlg = None
685    
686          topBox = wxBoxSizer(wxVERTICAL)          topBox = wxBoxSizer(wxVERTICAL)
687            panelBox = wxBoxSizer(wxVERTICAL)
688    
689          #topBox.Add(wxStaticText(self, -1, _("Layer: %s") % layer.Title()),          #panelBox.Add(wxStaticText(panel, -1, _("Layer: %s") % layer.Title()),
690              #0, wxALIGN_LEFT | wxALL, 4)              #0, wxALIGN_LEFT | wxALL, 4)
691          topBox.Add(wxStaticText(self, -1,          panelBox.Add(wxStaticText(panel, -1,
692                                  _("Layer Type: %s") % layer.ShapeType()),                                  _("Layer Type: %s") % layer.ShapeType()),
693              0, wxALIGN_LEFT | wxALL, 4)              0, wxALIGN_LEFT | wxALL, 4)
694    
# Line 602  class Classifier(NonModalDialog): Line 696  class Classifier(NonModalDialog):
696          #          #
697          # make field combo box          # make field combo box
698          #          #
699          self.fields = wxComboBox(self, ID_PROPERTY_SELECT, "",          self.fields = wxComboBox(panel, ID_PROPERTY_SELECT, "",
700                                       style = wxCB_READONLY)                                       style = wxCB_READONLY)
701    
702          self.num_cols = layer.table.field_count()          self.num_cols = layer.table.field_count()
# Line 619  class Classifier(NonModalDialog): Line 713  class Classifier(NonModalDialog):
713    
714              if name == field:              if name == field:
715                  self.__cur_field = i + 1                  self.__cur_field = i + 1
716                  self.fields.SetClientData(i + 1, self.originalClass)                  self.fields.SetClientData(i + 1,
717                                              copy.deepcopy(self.originalClass))
718              else:              else:
719                  self.fields.SetClientData(i + 1, None)                  self.fields.SetClientData(i + 1, None)
720    
721    
722          #          ###########
         #  
         #  
   
         self.fieldTypeText = wxStaticText(self, -1, "")  
         self.__SetFieldTypeText(self.__cur_field)  
723    
724          topBox.Add(self.fieldTypeText, 0, wxALIGN_LEFT | wxALL, 4)          self.fieldTypeText = wxStaticText(panel, -1, "")
725          #self.fieldTypeText.SetLabel("asdfadsfs")          panelBox.Add(self.fieldTypeText, 0,
726                         wxGROW | wxALIGN_LEFT | wxALL | wxADJUST_MINSIZE, 4)
727    
728          propertyBox = wxBoxSizer(wxHORIZONTAL)          propertyBox = wxBoxSizer(wxHORIZONTAL)
729          propertyBox.Add(wxStaticText(self, -1, _("Field: ")),          propertyBox.Add(wxStaticText(panel, -1, _("Field: ")),
730              0, wxALIGN_CENTER | wxALL, 4)              0, wxALIGN_LEFT | wxALL, 4)
731          propertyBox.Add(self.fields, 1, wxGROW|wxALL, 4)          propertyBox.Add(self.fields, 1, wxGROW|wxALL, 4)
732          EVT_COMBOBOX(self, ID_PROPERTY_SELECT, self._OnFieldSelect)          EVT_COMBOBOX(self, ID_PROPERTY_SELECT, self._OnFieldSelect)
733    
734          topBox.Add(propertyBox, 0, wxGROW, 4)          panelBox.Add(propertyBox, 0, wxGROW, 4)
735    
736    
737          #          #
738          # Classification data table          # Control Box
739          #          #
   
740          controlBox = wxBoxSizer(wxHORIZONTAL)          controlBox = wxBoxSizer(wxHORIZONTAL)
741    
         self.classGrid = ClassGrid(self)  
         self.__SetGridTable(self.__cur_field)  
   
         controlBox.Add(self.classGrid, 1, wxGROW, 0)  
   
         controlButtonBox = wxBoxSizer(wxVERTICAL)  
742    
743            ###########
744          #          #
745          # Control buttons:          # Control buttons:
746          #          #
747          self.controlButtons = []          self.controlButtons = []
748    
749          button = wxButton(self, ID_CLASSIFY_ADD, _("Add"))          controlButtonBox = wxBoxSizer(wxVERTICAL)
750    
751            button = wxButton(panel, ID_CLASSIFY_ADD, _("Add"))
752          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
753          self.controlButtons.append(button)          self.controlButtons.append(button)
754    
755          #button = wxButton(self, ID_CLASSIFY_GENRANGE, _("Generate Ranges"))          button = wxButton(panel, ID_CLASSIFY_EDITPROPS, _("Edit Properties"))
756          #controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
757          #self.controlButtons.append(button)          self.controlButtons.append(button)
758    
759            button = wxButton(panel, ID_CLASSIFY_GENCLASS, _("Generate Class"))
760            controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
761            self.controlButtons.append(button)
762    
763          button = wxButton(self, ID_CLASSIFY_MOVEUP, _("Move Up"))          button = wxButton(panel, ID_CLASSIFY_MOVEUP, _("Move Up"))
764          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
765          self.controlButtons.append(button)          self.controlButtons.append(button)
766    
767          button = wxButton(self, ID_CLASSIFY_MOVEDOWN, _("Move Down"))          button = wxButton(panel, ID_CLASSIFY_MOVEDOWN, _("Move Down"))
768          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)
769          self.controlButtons.append(button)          self.controlButtons.append(button)
770    
771          controlButtonBox.Add(60, 20, 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)          controlButtonBox.Add(60, 20, 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)
772    
773          button = wxButton(self, ID_CLASSIFY_REMOVE, _("Remove"))          button = wxButton(panel, ID_CLASSIFY_REMOVE, _("Remove"))
774          controlButtonBox.Add(button, 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)          controlButtonBox.Add(button, 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)
775          self.controlButtons.append(button)          self.controlButtons.append(button)
776    
777    
778            ###########
779            #
780            # Classification data table
781            #
782    
783            self.classGrid = ClassGrid(panel, self)
784            #self.__SetGridTable(self.__cur_field, group)
785            #self.fields.SetSelection(self.__cur_field)
786    
787            # calling __SelectField after creating the classGrid fills in the
788            # grid with the correct information
789            self.fields.SetSelection(self.__cur_field)
790            self.__SelectField(self.__cur_field, group = group)
791    
792            #self.classGrid.SelectGroup(group)
793    
794            controlBox.Add(self.classGrid, 1, wxGROW, 0)
795    
796    
797    
798          controlBox.Add(controlButtonBox, 0, wxGROW, 10)          controlBox.Add(controlButtonBox, 0, wxGROW, 10)
799          topBox.Add(controlBox, 1, wxGROW, 10)          panelBox.Add(controlBox, 1, wxGROW, 10)
800    
801          EVT_BUTTON(self, ID_CLASSIFY_ADD, self._OnAdd)          EVT_BUTTON(self, ID_CLASSIFY_ADD, self._OnAdd)
802            EVT_BUTTON(self, ID_CLASSIFY_EDITPROPS, self._OnEditGroupProperties)
803          EVT_BUTTON(self, ID_CLASSIFY_REMOVE, self._OnRemove)          EVT_BUTTON(self, ID_CLASSIFY_REMOVE, self._OnRemove)
804          EVT_BUTTON(self, ID_CLASSIFY_GENRANGE, self._OnGenRange)          EVT_BUTTON(self, ID_CLASSIFY_GENCLASS, self._OnGenClass)
805          EVT_BUTTON(self, ID_CLASSIFY_MOVEUP, self._OnMoveUp)          EVT_BUTTON(self, ID_CLASSIFY_MOVEUP, self._OnMoveUp)
806          EVT_BUTTON(self, ID_CLASSIFY_MOVEDOWN, self._OnMoveDown)          EVT_BUTTON(self, ID_CLASSIFY_MOVEDOWN, self._OnMoveDown)
807    
808            ###########
809    
810          buttonBox = wxBoxSizer(wxHORIZONTAL)          buttonBox = wxBoxSizer(wxHORIZONTAL)
811          buttonBox.Add(wxButton(self, ID_CLASSIFY_OK, _("OK")),          buttonBox.Add(wxButton(panel, ID_CLASSIFY_OK, _("OK")),
812                        0, wxALL, 4)                        0, wxALL, 4)
813          buttonBox.Add(60, 20, 0, wxALL, 4)          buttonBox.Add(60, 20, 0, wxALL, 4)
814          buttonBox.Add(wxButton(self, ID_CLASSIFY_APPLY, _("Apply")),          buttonBox.Add(wxButton(panel, ID_CLASSIFY_APPLY, _("Apply")),
815                        0, wxALL, 4)                        0, wxALL, 4)
816          buttonBox.Add(60, 20, 0, wxALL, 4)          buttonBox.Add(60, 20, 0, wxALL, 4)
817          buttonBox.Add(wxButton(self, ID_CLASSIFY_CANCEL, _("Cancel")),          buttonBox.Add(wxButton(panel, ID_CLASSIFY_CLOSE, _("Close")),
818                        0, wxALL, 4)                        0, wxALL, 4)
819          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)          buttonBox.Add(60, 20, 0, wxALL, 4)
820            buttonBox.Add(wxButton(panel, ID_CLASSIFY_CANCEL, _("Cancel")),
821                          0, wxALL, 4)
822            panelBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 0)
823    
824          EVT_BUTTON(self, ID_CLASSIFY_OK, self._OnOK)          EVT_BUTTON(self, ID_CLASSIFY_OK, self._OnOK)
825          EVT_BUTTON(self, ID_CLASSIFY_APPLY, self._OnApply)          EVT_BUTTON(self, ID_CLASSIFY_APPLY, self._OnApply)
826            EVT_BUTTON(self, ID_CLASSIFY_CLOSE, self._OnCloseBtn)
827          EVT_BUTTON(self, ID_CLASSIFY_CANCEL, self._OnCancel)          EVT_BUTTON(self, ID_CLASSIFY_CANCEL, self._OnCancel)
828    
829          self.fields.SetSelection(self.__cur_field)          ###########
830          self.__SelectField(self.__cur_field)  
831    
832          self.SetAutoLayout(true)          panel.SetAutoLayout(True)
833            panel.SetSizer(panelBox)
834            panelBox.SetSizeHints(panel)
835    
836            topBox.Add(panel, 1, wxGROW, 0)
837            panelBox.SetSizeHints(self)
838            self.SetAutoLayout(True)
839          self.SetSizer(topBox)          self.SetSizer(topBox)
         topBox.Fit(self)  
         topBox.SetSizeHints(self)  
840    
841            #self.Fit()
842            ######################
843    
844      def __BuildClassification(self, fieldIndex):          self.haveApplied = False
845    
846          numRows = self.classGrid.GetNumberRows()      def EditGroupProperties(self, row):
847          assert(numRows > 0) # there should always be a default row          table = self.classGrid.GetTable()
848            prop = table.GetValueAsCustom(row, COL_SYMBOL, None)
849    
850            # get a new ClassGroupProperties object and copy the
851            # values over to our current object
852            propDlg = SelectPropertiesDialog(NULL, prop, self.layer.ShapeType())
853    
854            self.Enable(False)
855            if propDlg.ShowModal() == wxID_OK:
856                new_prop = propDlg.GetClassGroupProperties()
857                table.SetValueAsCustom(row, COL_SYMBOL, None, new_prop)
858            self.Enable(True)
859            propDlg.Destroy()
860            
861        def _SetClassification(self, clazz):
862            
863            self.fields.SetClientData(self.__cur_field, clazz)
864            self.classGrid.GetTable().SetClassification(clazz)
865    
866        def __BuildClassification(self, fieldIndex, copyClass = False):
867    
868    #       numRows = self.classGrid.GetNumberRows()
869    #       assert numRows > 0  # there should always be a default row
870    
871          clazz = Classification()  #       clazz = Classification()
872          if fieldIndex == 0:          if fieldIndex == 0:
873              fieldName = None              fieldName = None
874              fieldType = None              fieldType = None
# Line 728  class Classifier(NonModalDialog): Line 876  class Classifier(NonModalDialog):
876              fieldName = self.fields.GetString(fieldIndex)              fieldName = self.fields.GetString(fieldIndex)
877              fieldType = self.layer.GetFieldType(fieldName)              fieldType = self.layer.GetFieldType(fieldName)
878    
879            clazz = self.classGrid.GetTable().GetClassification()
880    
881            if copyClass:
882                clazz = copy.deepcopy(clazz)
883    
884          clazz.SetField(fieldName)          clazz.SetField(fieldName)
885          clazz.SetFieldType(fieldType)          clazz.SetFieldType(fieldType)
886    
887    
888          table = self.classGrid.GetTable()  #       table = self.classGrid.GetTable()
889          clazz.SetDefaultGroup(table.GetClassGroup(0))  #       clazz.SetDefaultGroup(table.GetClassGroup(0))
890    
891          for i in range(1, numRows):  #       for i in range(1, numRows):
892              clazz.AddGroup(table.GetClassGroup(i))  #           clazz.AppendGroup(table.GetClassGroup(i))
893    
894          return clazz          return clazz
895    
896      def __SetGridTable(self, fieldIndex):      def __SetGridTable(self, fieldIndex, group = None):
897    
898          clazz = self.fields.GetClientData(fieldIndex)          clazz = self.fields.GetClientData(fieldIndex)
899    
# Line 755  class Classifier(NonModalDialog): Line 908  class Classifier(NonModalDialog):
908              fieldType = self.layer.GetFieldType(fieldName)              fieldType = self.layer.GetFieldType(fieldName)
909              clazz.SetFieldType(fieldType)              clazz.SetFieldType(fieldType)
910                                    
911          self.classGrid.CreateTable(clazz, self.layer.ShapeType())          self.classGrid.CreateTable(clazz, self.layer.ShapeType(), group)
   
   
   
     type2string = {None:             "None",  
                    FIELDTYPE_STRING: "Text",  
                    FIELDTYPE_INT:    "Integer",  
                    FIELDTYPE_DOUBLE: "Decimal"}  
912    
913      def __SetFieldTypeText(self, fieldIndex):      def __SetFieldTypeText(self, fieldIndex):
914          fieldName = self.fields.GetString(fieldIndex)          fieldName = self.fields.GetString(fieldIndex)
915          fieldType = self.layer.GetFieldType(fieldName)          fieldType = self.layer.GetFieldType(fieldName)
916    
917          assert(Classifier.type2string.has_key(fieldType))          assert Classifier.type2string.has_key(fieldType)
918    
919          text = Classifier.type2string[fieldType]          text = Classifier.type2string[fieldType]
920    
921          self.fieldTypeText.SetLabel(_("Field Type: %s") % text)          self.fieldTypeText.SetLabel(_("Field Type: %s") % text)
922    
923      def __SelectField(self, newIndex, oldIndex = -1):      def __SelectField(self, newIndex, oldIndex = -1, group = None):
924            """This method assumes that the current selection for the
925            combo has already been set by a call to SetSelection().
926            """
927    
928          assert(oldIndex >= -1)          assert oldIndex >= -1
929    
930          if oldIndex != -1:          if oldIndex != -1:
931              clazz = self.__BuildClassification(oldIndex)              clazz = self.__BuildClassification(oldIndex)
932              self.fields.SetClientData(oldIndex, clazz)              self.fields.SetClientData(oldIndex, clazz)
933    
934          self.__SetGridTable(newIndex)          self.__SetGridTable(newIndex, group)
935    
936          enabled = newIndex != 0          enabled = newIndex != 0
937    
# Line 792  class Classifier(NonModalDialog): Line 941  class Classifier(NonModalDialog):
941          self.__SetFieldTypeText(newIndex)          self.__SetFieldTypeText(newIndex)
942    
943    
944        def _OnEditGroupProperties(self, event):
945            sel = self.classGrid.GetCurrentSelection()
946    
947            if len(sel) == 1:
948                self.EditGroupProperties(sel[0])
949    
950      def _OnFieldSelect(self, event):      def _OnFieldSelect(self, event):
951          index = self.fields.GetSelection()          index = self.fields.GetSelection()
952          self.__SelectField(index, self.__cur_field)          self.__SelectField(index, self.__cur_field)
# Line 809  class Classifier(NonModalDialog): Line 964  class Classifier(NonModalDialog):
964          # to begin with or it has been modified          # to begin with or it has been modified
965          #          #
966          if clazz is None or self.classGrid.GetTable().IsModified():          if clazz is None or self.classGrid.GetTable().IsModified():
967              clazz = self.__BuildClassification(self.__cur_field)              clazz = self.__BuildClassification(self.__cur_field, True)
968    
969          self.layer.SetClassification(clazz)          self.layer.SetClassification(clazz)
970    
971            self.haveApplied = True
972    
973      def _OnOK(self, event):      def _OnOK(self, event):
974          self._OnApply(event)          self._OnApply(event)
975          self.OnClose(event)          self.Close()
976    
977        def _OnCloseBtn(self, event):
978            """Close is similar to Cancel except that any changes that were
979            made and applied remain applied, but the currently displayed
980            classification is discarded.
981            """
982    
983            self.Close()
984    
985      def _OnCancel(self, event):      def _OnCancel(self, event):
986          """The layer's current classification stays the same."""          """The layer's current classification stays the same."""
987          self.layer.SetClassification(self.originalClass)          if self.haveApplied:
988          self.OnClose(event)              self.layer.SetClassification(self.originalClass)
989    
990            self.Close()
991    
992      def _OnAdd(self, event):      def _OnAdd(self, event):
993          self.classGrid.AppendRows()          self.classGrid.AppendRows()
# Line 828  class Classifier(NonModalDialog): Line 995  class Classifier(NonModalDialog):
995      def _OnRemove(self, event):      def _OnRemove(self, event):
996          self.classGrid.DeleteSelectedRows()          self.classGrid.DeleteSelectedRows()
997    
998      def _OnGenRange(self, event):      def _OnGenClass(self, event):
999          print "Classifier._OnGenRange()"  
1000            #if self.genDlg is None:
1001            self.genDlg = ClassGenDialog(self, self.layer,
1002                              self.fields.GetString(self.__cur_field))
1003    
1004            EVT_CLOSE(self.genDlg, self._OnGenDialogClose)
1005    
1006            self.fields.Enable(False)
1007            self.controlButtons[BTN_EDIT].Enable(False)
1008            self.controlButtons[BTN_GEN].Enable(False)
1009    
1010            self.genDlg.Show()
1011            #if self.genDlg.ShowModal() == wxID_OK:
1012            #    clazz = self.genDlg.GetClassification()
1013            #    self.fields.SetClientData(self.__cur_field, clazz)
1014            #    self.classGrid.GetTable().SetClassification(clazz)
1015            #self.Enable(True)
1016            #self.genDlg.Destroy()
1017    
1018        def _OnGenDialogClose(self, event):
1019            self.genDlg.Destroy()
1020    
1021            self.fields.Enable(True)
1022            self.controlButtons[BTN_EDIT].Enable(True)
1023            self.controlButtons[BTN_GEN].Enable(True)
1024    
1025      def _OnMoveUp(self, event):      def _OnMoveUp(self, event):
1026          sel = self.classGrid.GetCurrentSelection()          sel = self.classGrid.GetCurrentSelection()
# Line 844  class Classifier(NonModalDialog): Line 1035  class Classifier(NonModalDialog):
1035                  table.SetClassGroup(i, x)                  table.SetClassGroup(i, x)
1036                  self.classGrid.ClearSelection()                  self.classGrid.ClearSelection()
1037                  self.classGrid.SelectRow(i - 1)                  self.classGrid.SelectRow(i - 1)
1038                    self.classGrid.MakeCellVisible(i - 1, 0)
1039    
1040      def _OnMoveDown(self, event):      def _OnMoveDown(self, event):
1041          sel = self.classGrid.GetCurrentSelection()          sel = self.classGrid.GetCurrentSelection()
# Line 858  class Classifier(NonModalDialog): Line 1050  class Classifier(NonModalDialog):
1050                  table.SetClassGroup(i + 1, x)                  table.SetClassGroup(i + 1, x)
1051                  self.classGrid.ClearSelection()                  self.classGrid.ClearSelection()
1052                  self.classGrid.SelectRow(i + 1)                  self.classGrid.SelectRow(i + 1)
1053                    self.classGrid.MakeCellVisible(i + 1, 0)
1054    
1055    
1056  ID_SELPROP_OK = 4001  ID_SELPROP_OK = 4001
# Line 873  class SelectPropertiesDialog(wxDialog): Line 1066  class SelectPropertiesDialog(wxDialog):
1066    
1067      def __init__(self, parent, prop, shapeType):      def __init__(self, parent, prop, shapeType):
1068          wxDialog.__init__(self, parent, -1, _("Select Properties"),          wxDialog.__init__(self, parent, -1, _("Select Properties"),
1069                            style = wxRESIZE_BORDER)                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
1070    
1071          self.prop = ClassGroupProperties(prop)          self.prop = ClassGroupProperties(prop)
1072    
# Line 885  class SelectPropertiesDialog(wxDialog): Line 1078  class SelectPropertiesDialog(wxDialog):
1078          previewBox = wxBoxSizer(wxVERTICAL)          previewBox = wxBoxSizer(wxVERTICAL)
1079          previewBox.Add(wxStaticText(self, -1, _("Preview:")),          previewBox.Add(wxStaticText(self, -1, _("Preview:")),
1080              0, wxALIGN_LEFT | wxALL, 4)              0, wxALIGN_LEFT | wxALL, 4)
1081          self.previewer = ClassDataPreviewer(None, self.prop, shapeType,  
1082                                              self, ID_SELPROP_PREVIEW, (40, 40))          self.previewWin = ClassGroupPropertiesCtrl(
1083          previewBox.Add(self.previewer, 1, wxGROW, 15)              self, ID_SELPROP_PREVIEW, self.prop, shapeType,
1084                (40, 40), wxSIMPLE_BORDER)
1085    
1086            self.previewWin.AllowEdit(False)
1087    
1088            previewBox.Add(self.previewWin, 1, wxGROW | wxALL, 4)
1089    
1090          itemBox.Add(previewBox, 1, wxALIGN_LEFT | wxALL | wxGROW, 0)          itemBox.Add(previewBox, 1, wxALIGN_LEFT | wxALL | wxGROW, 0)
1091    
# Line 896  class SelectPropertiesDialog(wxDialog): Line 1094  class SelectPropertiesDialog(wxDialog):
1094    
1095          lineColorBox = wxBoxSizer(wxHORIZONTAL)          lineColorBox = wxBoxSizer(wxHORIZONTAL)
1096          lineColorBox.Add(          lineColorBox.Add(
1097              wxButton(self, ID_SELPROP_STROKECLR, "Change Line Color"),              wxButton(self, ID_SELPROP_STROKECLR, _("Change Line Color")),
1098              1, wxALL | wxGROW, 4)              1, wxALL | wxGROW, 4)
1099          EVT_BUTTON(self, ID_SELPROP_STROKECLR, self._OnChangeLineColor)          EVT_BUTTON(self, ID_SELPROP_STROKECLR, self._OnChangeLineColor)
1100    
1101          lineColorBox.Add(          lineColorBox.Add(
1102              wxButton(self, ID_SELPROP_STROKECLRTRANS, "Transparent"),              wxButton(self, ID_SELPROP_STROKECLRTRANS, _("Transparent")),
1103              1, wxALL | wxGROW, 4)              1, wxALL | wxGROW, 4)
1104          EVT_BUTTON(self, ID_SELPROP_STROKECLRTRANS,          EVT_BUTTON(self, ID_SELPROP_STROKECLRTRANS,
1105                     self._OnChangeLineColorTrans)                     self._OnChangeLineColorTrans)
# Line 912  class SelectPropertiesDialog(wxDialog): Line 1110  class SelectPropertiesDialog(wxDialog):
1110          if shapeType != SHAPETYPE_ARC:          if shapeType != SHAPETYPE_ARC:
1111              fillColorBox = wxBoxSizer(wxHORIZONTAL)              fillColorBox = wxBoxSizer(wxHORIZONTAL)
1112              fillColorBox.Add(              fillColorBox.Add(
1113                  wxButton(self, ID_SELPROP_FILLCLR, "Change Fill Color"),                  wxButton(self, ID_SELPROP_FILLCLR, _("Change Fill Color")),
1114                  1, wxALL | wxGROW, 4)                  1, wxALL | wxGROW, 4)
1115              EVT_BUTTON(self, ID_SELPROP_FILLCLR, self._OnChangeFillColor)              EVT_BUTTON(self, ID_SELPROP_FILLCLR, self._OnChangeFillColor)
1116              fillColorBox.Add(              fillColorBox.Add(
1117                  wxButton(self, ID_SELPROP_FILLCLRTRANS, "Transparent"),                  wxButton(self, ID_SELPROP_FILLCLRTRANS, _("Transparent")),
1118                  1, wxALL | wxGROW, 4)                  1, wxALL | wxGROW, 4)
1119              EVT_BUTTON(self, ID_SELPROP_FILLCLRTRANS,              EVT_BUTTON(self, ID_SELPROP_FILLCLRTRANS,
1120                         self._OnChangeFillColorTrans)                         self._OnChangeFillColorTrans)
# Line 952  class SelectPropertiesDialog(wxDialog): Line 1150  class SelectPropertiesDialog(wxDialog):
1150          EVT_BUTTON(self, ID_SELPROP_OK, self._OnOK)          EVT_BUTTON(self, ID_SELPROP_OK, self._OnOK)
1151          EVT_BUTTON(self, ID_SELPROP_CANCEL, self._OnCancel)          EVT_BUTTON(self, ID_SELPROP_CANCEL, self._OnCancel)
1152                                                                                                                                                                    
1153          self.SetAutoLayout(true)          self.SetAutoLayout(True)
1154          self.SetSizer(topBox)          self.SetSizer(topBox)
1155          topBox.Fit(self)          topBox.Fit(self)
1156          topBox.SetSizeHints(self)          topBox.SetSizeHints(self)
# Line 965  class SelectPropertiesDialog(wxDialog): Line 1163  class SelectPropertiesDialog(wxDialog):
1163    
1164      def _OnSpin(self, event):      def _OnSpin(self, event):
1165          self.prop.SetLineWidth(self.spinCtrl.GetValue())          self.prop.SetLineWidth(self.spinCtrl.GetValue())
1166          self.previewer.Refresh()          self.previewWin.Refresh()
1167    
1168      def __GetColor(self, cur):      def __GetColor(self, cur):
1169          dialog = wxColourDialog(self)          dialog = wxColourDialog(self)
1170          dialog.GetColourData().SetColour(Color2wxColour(cur))          if cur is not Color.Transparent:
1171                dialog.GetColourData().SetColour(Color2wxColour(cur))
1172    
1173          ret = None          ret = None
1174          if dialog.ShowModal() == wxID_OK:          if dialog.ShowModal() == wxID_OK:
1175              ret = wxColour2Color(dialog.GetColourData().GetColour())              ret = wxColour2Color(dialog.GetColourData().GetColour())
# Line 982  class SelectPropertiesDialog(wxDialog): Line 1182  class SelectPropertiesDialog(wxDialog):
1182          clr = self.__GetColor(self.prop.GetLineColor())          clr = self.__GetColor(self.prop.GetLineColor())
1183          if clr is not None:          if clr is not None:
1184              self.prop.SetLineColor(clr)              self.prop.SetLineColor(clr)
1185          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer
1186    
1187      def _OnChangeLineColorTrans(self, event):      def _OnChangeLineColorTrans(self, event):
1188          self.prop.SetLineColor(Color.None)          self.prop.SetLineColor(Color.Transparent)
1189          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer
1190                    
1191      def _OnChangeFillColor(self, event):      def _OnChangeFillColor(self, event):
1192          clr = self.__GetColor(self.prop.GetFill())          clr = self.__GetColor(self.prop.GetFill())
1193          if clr is not None:          if clr is not None:
1194              self.prop.SetFill(clr)              self.prop.SetFill(clr)
1195          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer
1196    
1197      def _OnChangeFillColorTrans(self, event):      def _OnChangeFillColorTrans(self, event):
1198          self.prop.SetFill(Color.None)          self.prop.SetFill(Color.Transparent)
1199          self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer
1200    
1201      def GetClassGroupProperties(self):      def GetClassGroupProperties(self):
1202          return self.prop          return self.prop
1203    
1204    
1205  class ClassDataPreviewer(wxWindow):  class ClassDataPreviewWindow(wxWindow):
1206    
1207      def __init__(self, rect, prop, shapeType,      def __init__(self, rect, prop, shapeType,
1208                         parent = None, id = -1, size = wxDefaultSize):                         parent = None, id = -1, size = wxDefaultSize):
1209          if parent is not None:          if parent is not None:
1210              wxWindow.__init__(self, parent, id, size=size)              wxWindow.__init__(self, parent, id, (0, 0), size)
1211              EVT_PAINT(self, self._OnPaint)              EVT_PAINT(self, self._OnPaint)
1212    
1213          self.rect = rect          self.rect = rect
1214    
1215          self.prop = prop          self.prop = prop
1216          self.shapeType = shapeType          self.shapeType = shapeType
1217            self.previewer = ClassDataPreviewer()
1218    
1219        def GetProperties():
1220            return self.prop
1221    
1222      def _OnPaint(self, event):      def _OnPaint(self, event):
1223          dc = wxPaintDC(self)          dc = wxPaintDC(self)
# Line 1020  class ClassDataPreviewer(wxWindow): Line 1225  class ClassDataPreviewer(wxWindow):
1225          # XXX: this doesn't seem to be having an effect:          # XXX: this doesn't seem to be having an effect:
1226          dc.DestroyClippingRegion()          dc.DestroyClippingRegion()
1227    
1228          self.Draw(dc, None)          if self.rect is None:
1229                w, h = self.GetSize()
1230                rect = wxRect(0, 0, w, h)
1231            else:
1232                rect = self.rect
1233    
1234            self.previewer.Draw(dc, rect, self.prop, self.shapeType)
1235    
1236      def Draw(self, dc, rect, prop = None, shapeType = None):  class ClassDataPreviewer:
1237    
1238          if prop is None: prop = self.prop      def Draw(self, dc, rect, prop, shapeType):
1239          if shapeType is None: shapeType = self.shapeType  
1240            assert dc is not None
1241            assert isinstance(prop, ClassGroupProperties)
1242    
1243          if rect is None:          if rect is None:
1244              x = y = 0              x = 0
1245              w, h = self.GetClientSizeTuple()              y = 0
1246                w, h = dc.GetSize()
1247          else:          else:
1248              x = rect.GetX()              x = rect.GetX()
1249              y = rect.GetY()              y = rect.GetY()
# Line 1037  class ClassDataPreviewer(wxWindow): Line 1251  class ClassDataPreviewer(wxWindow):
1251              h = rect.GetHeight()              h = rect.GetHeight()
1252    
1253          stroke = prop.GetLineColor()          stroke = prop.GetLineColor()
1254          if stroke is Color.None:          if stroke is Color.Transparent:
1255              pen = wxTRANSPARENT_PEN              pen = wxTRANSPARENT_PEN
1256          else:          else:
1257              pen = wxPen(Color2wxColour(stroke),              pen = wxPen(Color2wxColour(stroke),
# Line 1045  class ClassDataPreviewer(wxWindow): Line 1259  class ClassDataPreviewer(wxWindow):
1259                          wxSOLID)                          wxSOLID)
1260    
1261          stroke = prop.GetFill()          stroke = prop.GetFill()
1262          if stroke is Color.None:          if stroke is Color.Transparent:
1263              brush = wxTRANSPARENT_BRUSH              brush = wxTRANSPARENT_BRUSH
1264          else:          else:
1265              brush = wxBrush(Color2wxColour(stroke), wxSOLID)              brush = wxBrush(Color2wxColour(stroke), wxSOLID)
# Line 1059  class ClassDataPreviewer(wxWindow): Line 1273  class ClassDataPreviewer(wxWindow):
1273                             wxPoint(x + w/2, y + h/4*3),                             wxPoint(x + w/2, y + h/4*3),
1274                             wxPoint(x + w, y)])                             wxPoint(x + w, y)])
1275    
1276          elif shapeType == SHAPETYPE_POINT or \          elif shapeType == SHAPETYPE_POINT:
              shapeType == SHAPETYPE_POLYGON:  
1277    
1278              dc.DrawCircle(x + w/2, y + h/2,              dc.DrawCircle(x + w/2, y + h/2,
1279                            (min(w, h) - prop.GetLineWidth())/2)                            (min(w, h) - prop.GetLineWidth())/2)
1280    
1281            elif shapeType == SHAPETYPE_POLYGON:
1282                dc.DrawRectangle(x, y, w, h)
1283    
1284  class ClassRenderer(wxPyGridCellRenderer):  class ClassRenderer(wxPyGridCellRenderer):
1285    
1286      def __init__(self, shapeType):      def __init__(self, shapeType):
1287          wxPyGridCellRenderer.__init__(self)          wxPyGridCellRenderer.__init__(self)
1288          self.previewer = ClassDataPreviewer(None, None, shapeType)          self.shapeType = shapeType
1289            self.previewer = ClassDataPreviewer()
1290    
1291      def Draw(self, grid, attr, dc, rect, row, col, isSelected):      def Draw(self, grid, attr, dc, rect, row, col, isSelected):
1292          data = grid.GetTable().GetClassGroup(row)          data = grid.GetTable().GetClassGroup(row)
# Line 1082  class ClassRenderer(wxPyGridCellRenderer Line 1299  class ClassRenderer(wxPyGridCellRenderer
1299                           rect.GetWidth(), rect.GetHeight())                           rect.GetWidth(), rect.GetHeight())
1300    
1301          if not isinstance(data, ClassGroupMap):          if not isinstance(data, ClassGroupMap):
1302              self.previewer.Draw(dc, rect, data.GetProperties())              self.previewer.Draw(dc, rect, data.GetProperties(), self.shapeType)
1303    
1304          if isSelected:          if isSelected:
1305              dc.SetPen(wxPen(wxColour(0 * 255, 0 * 255, 0 * 255),              dc.SetPen(wxPen(wxBLACK, 1, wxSOLID))
                       4, wxSOLID))  
1306              dc.SetBrush(wxTRANSPARENT_BRUSH)              dc.SetBrush(wxTRANSPARENT_BRUSH)
1307    
1308              dc.DrawRectangle(rect.GetX(), rect.GetY(),              dc.DrawRectangle(rect.GetX(), rect.GetY(),
1309                               rect.GetWidth(), rect.GetHeight())                               rect.GetWidth(), rect.GetHeight())
1310    
1311          dc.DestroyClippingRegion()          dc.DestroyClippingRegion()
1312    
1313    
1314    class ClassGroupPropertiesCtrl(wxWindow, wxControl):
1315    
1316        def __init__(self, parent, id, props, shapeType,
1317                     size = wxDefaultSize, style = 0):
1318    
1319            wxWindow.__init__(self, parent, id, size = size, style = style)
1320    
1321            self.SetProperties(props)
1322            self.SetShapeType(shapeType)
1323            self.AllowEdit(True)
1324    
1325            EVT_PAINT(self, self._OnPaint)
1326            EVT_LEFT_DCLICK(self, self._OnLeftDClick)
1327    
1328            self.previewer = ClassDataPreviewer()
1329    
1330        def _OnPaint(self, event):
1331            dc = wxPaintDC(self)
1332    
1333            # XXX: this doesn't seem to be having an effect:
1334            dc.DestroyClippingRegion()
1335    
1336            w, h = self.GetClientSize()
1337    
1338            self.previewer.Draw(dc,
1339                                wxRect(0, 0, w, h),
1340                                self.GetProperties(),
1341                                self.GetShapeType())
1342    
1343    
1344        def GetProperties(self):
1345            return self.props
1346    
1347        def SetProperties(self, props):
1348            self.props = props
1349            self.Refresh()
1350    
1351        def GetShapeType(self):
1352            return self.shapeType
1353    
1354        def SetShapeType(self, shapeType):
1355            self.shapeType = shapeType
1356            self.Refresh()
1357    
1358        def AllowEdit(self, allow):
1359            self.allowEdit = allow
1360    
1361        def DoEdit(self):
1362            if not self.allowEdit: return
1363    
1364            propDlg = SelectPropertiesDialog(NULL,
1365                                             self.GetProperties(),
1366                                             self.GetShapeType())
1367    
1368            if propDlg.ShowModal() == wxID_OK:
1369                new_prop = propDlg.GetClassGroupProperties()
1370                self.SetProperties(new_prop)
1371                self.Refresh()
1372    
1373            propDlg.Destroy()
1374    
1375        def _OnLeftDClick(self, event):
1376            self.DoEdit()

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26