/[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 615 by jonathan, Mon Apr 7 08:57:20 2003 UTC revision 1307 by jonathan, Thu Jun 26 17:00:17 2003 UTC
# Line 18  from wxPython.wx import * Line 18  from wxPython.wx import *
18  from wxPython.grid import *  from wxPython.grid import *
19    
20  from Thuban import _  from Thuban import _
21  from Thuban.common import *  from Thuban.UI.common import Color2wxColour, wxColour2Color
 from Thuban.UI.common import *  
22    
23  from Thuban.Model.classification import *  from Thuban.Model.messages import MAP_LAYERS_REMOVED, LAYER_SHAPESTORE_REPLACED
24    from Thuban.Model.range import Range
25    from Thuban.Model.classification import \
26        Classification, ClassGroupDefault, \
27        ClassGroupSingleton, ClassGroupRange, ClassGroupMap, \
28        ClassGroupProperties
29    
30  from Thuban.Model.color import Color  from Thuban.Model.color import Color
31    
32  from Thuban.Model.layer import Layer, SHAPETYPE_ARC, SHAPETYPE_POLYGON, SHAPETYPE_POINT  from Thuban.Model.layer import Layer, RasterLayer, \
33        SHAPETYPE_ARC, SHAPETYPE_POLYGON, SHAPETYPE_POINT
34    
35  from Thuban.UI.classgen import ClassGenDialog, ClassGenerator  from Thuban.UI.classgen import ClassGenDialog
36    
37  from dialogs import NonModalDialog  from dialogs import NonModalNonParentDialog
38    
 # widget id's  
 ID_PROPERTY_SELECT = 4010  
39  ID_CLASS_TABLE = 40011  ID_CLASS_TABLE = 40011
40    
 ID_CLASSIFY_OK = 4001  
 ID_CLASSIFY_CANCEL = 4002  
 ID_CLASSIFY_ADD = 4003  
 ID_CLASSIFY_GENCLASS = 4004  
 ID_CLASSIFY_REMOVE = 4005  
 ID_CLASSIFY_MOVEUP = 4006  
 ID_CLASSIFY_MOVEDOWN = 4007  
 ID_CLASSIFY_APPLY = 4008  
 ID_CLASSIFY_EDITPROPS = 4009  
 ID_CLASSIFY_CLOSE = 4010  
41    
42  # table columns  # table columns
43  COL_SYMBOL = 0  COL_VISIBLE = 0
44  COL_VALUE  = 1  COL_SYMBOL  = 1
45  COL_LABEL  = 2  COL_VALUE   = 2
46    COL_LABEL   = 3
47    NUM_COLS    = 4
48    
49  # indices into the client data lists in Classifier.fields  # indices into the client data lists in Classifier.fields
50  FIELD_CLASS = 0  FIELD_CLASS = 0
# Line 73  class ClassGrid(wxGrid): Line 68  class ClassGrid(wxGrid):
68                   use for display.                   use for display.
69          """          """
70    
71          #wxGrid.__init__(self, parent, ID_CLASS_TABLE, size = (340, 160))          wxGrid.__init__(self, parent, ID_CLASS_TABLE, style = 0)
         wxGrid.__init__(self, parent, ID_CLASS_TABLE)  
         #self.SetTable(ClassTable(fieldData, layer.ShapeType(), self), True)  
72    
73          self.classifier = classifier          self.classifier = classifier
74    
# Line 87  class ClassGrid(wxGrid): Line 80  class ClassGrid(wxGrid):
80          EVT_GRID_COL_SIZE(self, self._OnCellResize)          EVT_GRID_COL_SIZE(self, self._OnCellResize)
81          EVT_GRID_ROW_SIZE(self, self._OnCellResize)          EVT_GRID_ROW_SIZE(self, self._OnCellResize)
82    
83          #print "123123123: ", ('Show' in dir(self))      #def GetCellAttr(self, row, col):
84            #print "GetCellAttr ", row, col
85      #def Show(self):          #wxGrid.GetCellAttr(self, row, col)
         #print "SHOW!"  
   
     #def Refresh(self):  
         #self.Show()  
     #def Update(self):  
         #self.Show()  
86    
87      def CreateTable(self, clazz, shapeType, group = None):      def CreateTable(self, clazz, shapeType, group = None):
88    
# Line 103  class ClassGrid(wxGrid): Line 90  class ClassGrid(wxGrid):
90    
91          table = self.GetTable()          table = self.GetTable()
92          if table is None:          if table is None:
93              w = self.GetDefaultColSize() * 3 + self.GetDefaultRowLabelSize()              w = self.GetDefaultColSize() * NUM_COLS \
94              h = self.GetDefaultRowSize() * 4 + self.GetDefaultColLabelSize()                  + self.GetDefaultRowLabelSize()
95                h = self.GetDefaultRowSize() * 4 \
96                    + self.GetDefaultColLabelSize()
97    
98              self.SetDimensions(-1, -1, w, h)              self.SetDimensions(-1, -1, w, h)
99              self.SetSizeHints(w, h, -1, -1)              self.SetSizeHints(w, h, -1, -1)
100              table = ClassTable(self)              table = ClassTable(self)
# Line 114  class ClassGrid(wxGrid): Line 104  class ClassGrid(wxGrid):
104          self.SetSelectionMode(wxGrid.wxGridSelectRows)          self.SetSelectionMode(wxGrid.wxGridSelectRows)
105          self.ClearSelection()          self.ClearSelection()
106    
         #print "8------------------"  
107          table.Reset(clazz, shapeType, group)          table.Reset(clazz, shapeType, group)
         #print "9------------------"  
   
 #   def Show(self, show = True):  
 #       print "SHOW!"  
 #       wxGrid.Show(self, show)  
   
 #       sel = self.GetCurrentSelection()  
   
 #       print "( 1"  
 #       if len(sel) == 1:  
 #           print "( 2"  
 #           self.MakeCellVisible(sel[0], 0)  
108    
109      def GetCurrentSelection(self):      def GetCurrentSelection(self):
110          """Return the currently highlighted rows as an increasing list          """Return the currently highlighted rows as an increasing list
111             of row numbers."""             of row numbers."""
         #print "@@ ", self.currentSelection  
112          sel = copy.copy(self.currentSelection)          sel = copy.copy(self.currentSelection)
113          sel.sort()          sel.sort()
114          return sel          return sel
# Line 140  class ClassGrid(wxGrid): Line 116  class ClassGrid(wxGrid):
116      def GetSelectedRows(self):      def GetSelectedRows(self):
117          return self.GetCurrentSelection()          return self.GetCurrentSelection()
118    
119      def SetCellRenderer(self, row, col):      #def SetCellRenderer(self, row, col, renderer):
120          raise ValueError(_("Must not allow setting of renderer in ClassGrid!"))          #raise ValueError(_("Must not allow setting of renderer in ClassGrid!"))
121    
122      #      #
123      # [Set|Get]Table is taken from http://wiki.wxpython.org      # [Set|Get]Table is taken from http://wiki.wxpython.org
# Line 216  class ClassGrid(wxGrid): Line 192  class ClassGrid(wxGrid):
192    
193          assert table is not None          assert table is not None
194    
   
         #print "-- ", group  
195          for i in range(table.GetNumberRows()):          for i in range(table.GetNumberRows()):
196              g = table.GetClassGroup(i)              g = table.GetClassGroup(i)
             #print "1", g  
197              if g is group:              if g is group:
                 #print "2"  
198                  self.SelectRow(i)                  self.SelectRow(i)
199                  if makeVisible:                  if makeVisible:
                     #print "3"  
200                      self.MakeCellVisible(i, 0)                      self.MakeCellVisible(i, 0)
201                  break                  break
202    
           
   
203  #  #
204  # 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!
205  #  #
# Line 243  class ClassGrid(wxGrid): Line 212  class ClassGrid(wxGrid):
212  #                                  sel = False))  #                                  sel = False))
213    
214      def _OnCellDClick(self, event):      def _OnCellDClick(self, event):
215          """Handle a double on a cell."""          """Handle a double click on a cell."""
216    
217          r = event.GetRow()          r = event.GetRow()
218          c = event.GetCol()          c = event.GetCol()
         if c == COL_SYMBOL:  
             self.classifier.EditGroupProperties(r)  
219    
220            if c == COL_SYMBOL:
221                self.classifier.EditSymbol(r)
222            else:
223                event.Skip()
224    
225      #      #
226      # _OnSelectedRange() and _OnSelectedCell() were borrowed      # _OnSelectedRange() and _OnSelectedCell() were borrowed
# Line 261  class ClassGrid(wxGrid): Line 232  class ClassGrid(wxGrid):
232          if event.Selecting():          if event.Selecting():
233              for index in range( event.GetTopRow(), event.GetBottomRow()+1):              for index in range( event.GetTopRow(), event.GetBottomRow()+1):
234                  if index not in self.currentSelection:                  if index not in self.currentSelection:
                     #print "    ", index  
235                      self.currentSelection.append( index )                      self.currentSelection.append( index )
236          else:          else:
237              for index in range( event.GetTopRow(), event.GetBottomRow()+1):              for index in range( event.GetTopRow(), event.GetBottomRow()+1):
238                  while index in self.currentSelection:                  while index in self.currentSelection:
                     #print "    ", index  
239                      self.currentSelection.remove( index )                      self.currentSelection.remove( index )
240          #self.ConfigureForSelection()          #self.ConfigureForSelection()
241    
         #print self.GetCurrentSelection()  
242          event.Skip()          event.Skip()
243    
244      def _OnSelectedCell( self, event ):      def _OnSelectedCell( self, event ):
245          """Internal update to the selection tracking list"""          """Internal update to the selection tracking list"""
         #print "selecting cell: ", event.GetRow()  
246          self.currentSelection = [ event.GetRow() ]          self.currentSelection = [ event.GetRow() ]
247          #self.ConfigureForSelection()          #self.ConfigureForSelection()
248          event.Skip()          event.Skip()
249    
250      def _OnCellResize(self, event):      def _OnCellResize(self, event):
251          self.FitInside()          self.FitInside()
252            event.Skip()
253    
254  class ClassTable(wxPyGridTableBase):  class ClassTable(wxPyGridTableBase):
255      """Represents the underlying data structure for the grid."""      """Represents the underlying data structure for the grid."""
256    
257      NUM_COLS = 3      __col_labels = [_("Visible"), _("Symbol"), _("Value"), _("Label")]
   
     __col_labels = [_("Symbol"), _("Value"), _("Label")]  
258    
259    
260      def __init__(self, view = None):      def __init__(self, view = None):
# Line 302  class ClassTable(wxPyGridTableBase): Line 268  class ClassTable(wxPyGridTableBase):
268    
269          wxPyGridTableBase.__init__(self)          wxPyGridTableBase.__init__(self)
270    
271          self.SetView(view)          assert len(ClassTable.__col_labels) == NUM_COLS
272    
273          self.clazz = None          self.clazz = None
274            self.__colAttr = {}
275    
276          #self.Reset(clazz, shapeType)          self.SetView(view)
277    
278      def Reset(self, clazz, shapeType, group = None):      def Reset(self, clazz, shapeType, group = None):
279          """Reset the table with the given data.          """Reset the table with the given data.
# Line 330  class ClassTable(wxPyGridTableBase): Line 298  class ClassTable(wxPyGridTableBase):
298    
299          self.SetClassification(clazz, group)          self.SetClassification(clazz, group)
300          self.__Modified(-1)          self.__Modified(-1)
301          #print "11------------------"  
302            self.__colAttr = {}
303    
304            attr = wxGridCellAttr()
305            attr.SetEditor(wxGridCellBoolEditor())
306            attr.SetRenderer(wxGridCellBoolRenderer())
307            attr.SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER)
308            self.__colAttr[COL_VISIBLE] = attr
309    
310            attr = wxGridCellAttr()
311            attr.SetRenderer(ClassRenderer(self.shapeType))
312            attr.SetReadOnly()
313            self.__colAttr[COL_SYMBOL] = attr
314    
315          self.GetView().EndBatch()          self.GetView().EndBatch()
316          self.GetView().FitInside()          self.GetView().FitInside()
# Line 344  class ClassTable(wxPyGridTableBase): Line 324  class ClassTable(wxPyGridTableBase):
324    
325          old_len = self.GetNumberRows()          old_len = self.GetNumberRows()
326    
         #print "9------------------"  
         #  
         # copy the data out of the classification and into our  
         # array  
         #  
327          row = -1          row = -1
 #       for g in clazz:  
 #           ng = copy.deepcopy(g)  
 #           self.__SetRow(None, ng)  
 #           if g is group:  
 #               row = self.GetNumberRows() - 1  
 #               #print "selecting row..."  
   
         #print "10------------------"  
   
         #self.clazz = copy.deepcopy(clazz)  
328          self.clazz = clazz          self.clazz = clazz
329    
330          self.__NotifyRowChanges(old_len, self.GetNumberRows())          self.__NotifyRowChanges(old_len, self.GetNumberRows())
331    
332            #
333            # XXX: this is dead code at the moment
334            #
335          if row > -1:          if row > -1:
336              self.GetView().ClearSelection()              self.GetView().ClearSelection()
337              self.GetView().SelectRow(row)              self.GetView().SelectRow(row)
# Line 371  class ClassTable(wxPyGridTableBase): Line 339  class ClassTable(wxPyGridTableBase):
339    
340          self.__Modified()          self.__Modified()
341    
342    
343          self.GetView().EndBatch()          self.GetView().EndBatch()
344          self.GetView().FitInside()          self.GetView().FitInside()
345    
# Line 435  class ClassTable(wxPyGridTableBase): Line 404  class ClassTable(wxPyGridTableBase):
404              if isinstance(group, ClassGroupMap):       return _("Map")              if isinstance(group, ClassGroupMap):       return _("Map")
405    
406          assert False # shouldn't get here          assert False # shouldn't get here
407          return _("")          return ""
408    
409      def GetNumberRows(self):      def GetNumberRows(self):
410          """Return the number of rows."""          """Return the number of rows."""
# Line 446  class ClassTable(wxPyGridTableBase): Line 415  class ClassTable(wxPyGridTableBase):
415    
416      def GetNumberCols(self):      def GetNumberCols(self):
417          """Return the number of columns."""          """Return the number of columns."""
418          return self.NUM_COLS          return NUM_COLS
419    
420      def IsEmptyCell(self, row, col):      def IsEmptyCell(self, row, col):
421          """Determine if a cell is empty. This is always false."""          """Determine if a cell is empty. This is always false."""
# Line 464  class ClassTable(wxPyGridTableBase): Line 433  class ClassTable(wxPyGridTableBase):
433          """          """
434    
435          self.SetValueAsCustom(row, col, None, value)          self.SetValueAsCustom(row, col, None, value)
         self.__Modified()  
436                
437      def GetValueAsCustom(self, row, col, typeName):      def GetValueAsCustom(self, row, col, typeName):
438          """Return the object that is used to represent the given          """Return the object that is used to represent the given
# Line 479  class ClassTable(wxPyGridTableBase): Line 447  class ClassTable(wxPyGridTableBase):
447              group = self.clazz.GetGroup(row - 1)              group = self.clazz.GetGroup(row - 1)
448    
449    
450            if col == COL_VISIBLE:
451                return group.IsVisible()
452    
453          if col == COL_SYMBOL:          if col == COL_SYMBOL:
454              return group.GetProperties()              return group.GetProperties()
455    
# Line 493  class ClassTable(wxPyGridTableBase): Line 464  class ClassTable(wxPyGridTableBase):
464          elif isinstance(group, ClassGroupSingleton):          elif isinstance(group, ClassGroupSingleton):
465              return group.GetValue()              return group.GetValue()
466          elif isinstance(group, ClassGroupRange):          elif isinstance(group, ClassGroupRange):
467              return _("%s - %s") % (group.GetMin(), group.GetMax())              return group.GetRange()
468    
469          assert(False) # shouldn't get here          assert False # shouldn't get here
470          return None          return None
471    
472      def __ParseInput(self, value):      def __ParseInput(self, value):
473          """Try to determine what kind of input value is          """Try to determine what kind of input value is
474             (string, number, or range)             (string, number, or range)
475    
476          Returns a tuple of length one if there is a single          Returns a tuple (type, data) where type is 0 if data is
477          value, or of length two if it is a range.          a singleton value, or 1 if is a range
478          """          """
479    
480          type = self.fieldType          type = self.fieldType
481    
482          if type == FIELDTYPE_STRING:          if type == FIELDTYPE_STRING:
483              return (value,)              return (0, value)
484          elif type == FIELDTYPE_INT or type == FIELDTYPE_DOUBLE:          elif type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):
   
485              if type == FIELDTYPE_INT:              if type == FIELDTYPE_INT:
486                    # the float call allows the user to enter 1.0 for 1
487                  conv = lambda p: int(float(p))                  conv = lambda p: int(float(p))
488              else:              else:
489                  conv = lambda p: p                  conv = float
490    
491              #              #
492              # first try to take the input as a single number              # first try to take the input as a single number
493              # if there's an exception try to break it into              # if there's an exception try to break it into
494              # a range seperated by a '-'. take care to ignore              # a range. if there is an exception here, let it
495              # a leading '-' as that could be for a negative number.              # pass up to the calling function.
             # then try to parse the individual parts. if there  
             # is an exception here, let it pass up to the calling  
             # function.  
496              #              #
497              try:              try:
498                  return (conv(Str2Num(value)),)                  return (0, conv(value))
499              except ValueError:              except ValueError:
500                  i = value.find('-')                  return (1, Range(value))
                 if i == 0:  
                     i = value.find('-', 1)  
   
                 return (conv(Str2Num(value[:i])), conv(Str2Num(value[i+1:])))  
501    
502          assert False  # shouldn't get here          assert False  # shouldn't get here
503          return (0,)          return (0,None)
               
504    
505      def SetValueAsCustom(self, row, col, typeName, value):      def SetValueAsCustom(self, row, col, typeName, value):
506          """Set the cell specified by 'row' and 'col' to 'value'.          """Set the cell specified by 'row' and 'col' to 'value'.
# Line 551  class ClassTable(wxPyGridTableBase): Line 514  class ClassTable(wxPyGridTableBase):
514          typeName -- unused, but needed to overload wxPyGridTableBase          typeName -- unused, but needed to overload wxPyGridTableBase
515          """          """
516    
517          assert col >= 0 and col < self.GetNumberCols()          assert 0 <= col < self.GetNumberCols()
518          assert row >= 0 and row < self.GetNumberRows()          assert 0 <= row < self.GetNumberRows()
519    
520          if row == 0:          if row == 0:
521              group = self.clazz.GetDefaultGroup()              group = self.clazz.GetDefaultGroup()
# Line 561  class ClassTable(wxPyGridTableBase): Line 524  class ClassTable(wxPyGridTableBase):
524    
525          mod = True # assume the data will change          mod = True # assume the data will change
526    
527          if col == COL_SYMBOL:          if col == COL_VISIBLE:
528                group.SetVisible(value)
529            elif col == COL_SYMBOL:
530              group.SetProperties(value)              group.SetProperties(value)
531          elif col == COL_LABEL:          elif col == COL_LABEL:
532              group.SetLabel(value)              group.SetLabel(value)
# Line 589  class ClassTable(wxPyGridTableBase): Line 554  class ClassTable(wxPyGridTableBase):
554                      # changing the underlying group type if the                      # changing the underlying group type if the
555                      # group was a singleton and a range was entered                      # group was a singleton and a range was entered
556                      #                      #
557                      if len(dataInfo) == 1:                      if dataInfo[0] == 0:
558                          if not isinstance(group, ClassGroupSingleton):                          if not isinstance(group, ClassGroupSingleton):
559                              ngroup = ClassGroupSingleton(prop = props)                              ngroup = ClassGroupSingleton(props = props)
560                              changed = True                              changed = True
561                          ngroup.SetValue(dataInfo[0])                          ngroup.SetValue(dataInfo[1])
562                      elif len(dataInfo) == 2:                      elif dataInfo[0] == 1:
563                          if not isinstance(group, ClassGroupRange):                          if not isinstance(group, ClassGroupRange):
564                              ngroup = ClassGroupRange(prop = props)                              ngroup = ClassGroupRange(props = props)
565                              changed = True                              changed = True
566                          ngroup.SetRange(dataInfo[0], dataInfo[1])                          ngroup.SetRange(dataInfo[1])
567                      else:                      else:
568                          assert False                          assert False
569                          pass                          pass
# Line 617  class ClassTable(wxPyGridTableBase): Line 582  class ClassTable(wxPyGridTableBase):
582      def GetAttr(self, row, col, someExtraParameter):      def GetAttr(self, row, col, someExtraParameter):
583          """Returns the cell attributes"""          """Returns the cell attributes"""
584    
585          attr = wxGridCellAttr()          return self.__colAttr.get(col, wxGridCellAttr()).Clone()
         #attr = wxPyGridTableBase.GetAttr(self, row, col, someExtraParameter)  
   
         if col == COL_SYMBOL:  
             # we need to create a new renderer each time, because  
             # SetRenderer takes control of the parameter  
             attr.SetRenderer(ClassRenderer(self.shapeType))  
             attr.SetReadOnly()  
   
         return attr  
586    
587      def GetClassGroup(self, row):      def GetClassGroup(self, row):
588          """Return the ClassGroup object representing row 'row'."""          """Return the ClassGroup object representing row 'row'."""
# Line 692  class ClassTable(wxPyGridTableBase): Line 648  class ClassTable(wxPyGridTableBase):
648              self.__NotifyRowChanges(old_len, self.GetNumberRows())              self.__NotifyRowChanges(old_len, self.GetNumberRows())
649    
650    
651  class Classifier(NonModalDialog):  ID_PROPERTY_REVERT = 4002
652    ID_PROPERTY_ADD = 4003
653    ID_PROPERTY_GENCLASS = 4004
654    ID_PROPERTY_REMOVE = 4005
655    ID_PROPERTY_MOVEUP = 4006
656    ID_PROPERTY_MOVEDOWN = 4007
657    ID_PROPERTY_TRY = 4008
658    ID_PROPERTY_EDITSYM = 4009
659    ID_PROPERTY_SELECT = 4011
660    ID_PROPERTY_TITLE = 4012
661    ID_PROPERTY_FIELDTEXT = 4013
662    
663    BTN_ADD = 0
664    BTN_EDIT = 1
665    BTN_GEN = 2
666    BTN_UP = 3
667    BTN_DOWN = 4
668    BTN_RM = 5
669    
670    EB_LAYER_TITLE = 0
671    EB_SELECT_FIELD = 1
672    EB_GEN_CLASS = 2
673    
674      def __init__(self, parent, name, layer, group = None):  class Classifier(NonModalNonParentDialog):
         NonModalDialog.__init__(self, parent, name,  
                                 _("Classifier: %s") % layer.Title())  
675    
676          panel = wxPanel(self, -1, size=(100, 100))      type2string = {None:             _("None"),
677                       FIELDTYPE_STRING: _("Text"),
678                       FIELDTYPE_INT:    _("Integer"),
679                       FIELDTYPE_DOUBLE: _("Decimal")}
680    
681          self.layer = layer      def __init__(self, parent, name, map, layer, group = None):
682            NonModalNonParentDialog.__init__(self, parent, name, "")
683    
684          self.originalClass = self.layer.GetClassification()          self.__SetTitle(layer.Title())
         field = self.originalClass.GetField()  
         fieldType = self.originalClass.GetFieldType()  
685    
686          topBox = wxBoxSizer(wxVERTICAL)          self.layer = layer
687          panelBox = wxBoxSizer(wxVERTICAL)          self.map = map
688    
689          #panelBox.Add(wxStaticText(panel, -1, _("Layer: %s") % layer.Title()),          self.map.Subscribe(MAP_LAYERS_REMOVED, self.map_layers_removed)
690              #0, wxALIGN_LEFT | wxALL, 4)          self.layer.Subscribe(LAYER_SHAPESTORE_REPLACED,
691          panelBox.Add(wxStaticText(panel, -1,                               self.layer_shapestore_replaced)
                                 _("Layer Type: %s") % layer.ShapeType()),  
             0, wxALIGN_LEFT | wxALL, 4)  
692    
693            self.genDlg = None
694    
695            ############################
696            # Create the controls
697          #          #
         # make field combo box  
         #  
         self.fields = wxComboBox(panel, ID_PROPERTY_SELECT, "",  
                                      style = wxCB_READONLY)  
698    
699          self.num_cols = layer.table.field_count()          panel = wxPanel(self, -1)
         # just assume the first field in case one hasn't been  
         # specified in the file.  
         self.__cur_field = 0  
   
         self.fields.Append("<None>")  
         self.fields.SetClientData(0, None)  
   
         for i in range(self.num_cols):  
             type, name, len, decc = layer.table.field_info(i)  
             self.fields.Append(name)  
   
             if name == field:  
                 self.__cur_field = i + 1  
                 self.fields.SetClientData(i + 1,  
                                           copy.deepcopy(self.originalClass))  
             else:  
                 self.fields.SetClientData(i + 1, None)  
   
   
         ###########  
700    
701            text_title = wxTextCtrl(panel, ID_PROPERTY_TITLE, layer.Title())
702          self.fieldTypeText = wxStaticText(panel, -1, "")          self.fieldTypeText = wxStaticText(panel, -1, "")
         panelBox.Add(self.fieldTypeText, 0,  
                      wxGROW | wxALIGN_LEFT | wxALL | wxADJUST_MINSIZE, 4)  
   
         propertyBox = wxBoxSizer(wxHORIZONTAL)  
         propertyBox.Add(wxStaticText(panel, -1, _("Field: ")),  
             0, wxALIGN_LEFT | wxALL, 4)  
         propertyBox.Add(self.fields, 1, wxGROW|wxALL, 4)  
         EVT_COMBOBOX(self, ID_PROPERTY_SELECT, self._OnFieldSelect)  
703    
704          panelBox.Add(propertyBox, 0, wxGROW, 4)          if layer.HasClassification():
705                self.originalClass = self.layer.GetClassification()
706                field = self.originalClass.GetField()
707                fieldType = self.originalClass.GetFieldType()
708    
709                table = layer.ShapeStore().Table()
710                #
711                # make field choice box
712                #
713                self.fields = wxChoice(panel, ID_PROPERTY_SELECT,)
714    
715          #              self.num_cols = table.NumColumns()
716          # Control Box              # just assume the first field in case one hasn't been
717          #              # specified in the file.
718          controlBox = wxBoxSizer(wxHORIZONTAL)              self.__cur_field = 0
719    
720                self.fields.Append("<None>")
721    
722          ###########              if self.originalClass.GetFieldType() is None:
723          #                  self.fields.SetClientData(0, copy.deepcopy(self.originalClass))
724          # Control buttons:              else:
725          #                  self.fields.SetClientData(0, None)
         self.controlButtons = []  
726    
727          controlButtonBox = wxBoxSizer(wxVERTICAL)              for i in range(self.num_cols):
728                    name = table.Column(i).name
729                    self.fields.Append(name)
730    
731                    if name == field:
732                        self.__cur_field = i + 1
733                        self.fields.SetClientData(i + 1,
734                                                copy.deepcopy(self.originalClass))
735                    else:
736                        self.fields.SetClientData(i + 1, None)
737    
738          button = wxButton(panel, ID_CLASSIFY_ADD, _("Add"))              button_gen = wxButton(panel, ID_PROPERTY_GENCLASS,
739          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)                  _("Generate Class"))
740          self.controlButtons.append(button)              button_add = wxButton(panel, ID_PROPERTY_ADD,
741                    _("Add"))
742                button_moveup = wxButton(panel, ID_PROPERTY_MOVEUP,
743                    _("Move Up"))
744                button_movedown = wxButton(panel, ID_PROPERTY_MOVEDOWN,
745                    _("Move Down"))
746                button_edit = wxButton(panel, ID_PROPERTY_EDITSYM,
747                    _("Edit Symbol"))
748                button_remove = wxButton(panel, ID_PROPERTY_REMOVE,
749                    _("Remove"))
750    
751                self.classGrid = ClassGrid(panel, self)
752    
753                # calling __SelectField after creating the classGrid fills in the
754                # grid with the correct information
755                self.fields.SetSelection(self.__cur_field)
756                self.__SelectField(self.__cur_field, group = group)
757    
758            button_try = wxButton(self, ID_PROPERTY_TRY, _("Try"))
759            button_revert = wxButton(self, ID_PROPERTY_REVERT, _("Revert"))
760            button_ok = wxButton(self, wxID_OK, _("OK"))
761            button_ok.SetDefault()
762            button_close = wxButton(self, wxID_CANCEL, _("Close"))
763    
764          button = wxButton(panel, ID_CLASSIFY_EDITPROPS, _("Edit Properties"))          ############################
765          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)          # Layout the controls
766          self.controlButtons.append(button)          #
767    
768          button = wxButton(panel, ID_CLASSIFY_GENCLASS, _("Generate Class"))          topBox = wxBoxSizer(wxVERTICAL)
769          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)          panelBox = wxBoxSizer(wxVERTICAL)
         self.controlButtons.append(button)  
770    
771          button = wxButton(panel, ID_CLASSIFY_MOVEUP, _("Move Up"))          sizer = wxBoxSizer(wxHORIZONTAL)
772          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)          sizer.Add(wxStaticText(panel, -1, _("Title: ")),
773          self.controlButtons.append(button)              0, wxALIGN_LEFT | wxALL | wxALIGN_CENTER_VERTICAL, 4)
774            sizer.Add(text_title, 1, wxGROW, 0)
775    
776          button = wxButton(panel, ID_CLASSIFY_MOVEDOWN, _("Move Down"))          panelBox.Add(sizer, 0, wxGROW, 4)
         controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)  
         self.controlButtons.append(button)  
777    
778          controlButtonBox.Add(60, 20, 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)          if isinstance(layer, RasterLayer):
779                type = "Image"
780            else:
781                type = layer.ShapeType()
782    
783          button = wxButton(panel, ID_CLASSIFY_REMOVE, _("Remove"))          panelBox.Add(wxStaticText(panel, -1, _("Type: %s") % type),
784          controlButtonBox.Add(button, 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)              0, wxALIGN_LEFT | wxALL, 4)
         self.controlButtons.append(button)  
785    
786            if layer.HasClassification():
787    
788          ###########              classBox = wxStaticBoxSizer(
789          #                          wxStaticBox(panel, -1, _("Classification")), wxVERTICAL)
         # Classification data table  
         #  
790    
         self.classGrid = ClassGrid(panel, self)  
         #self.__SetGridTable(self.__cur_field, group)  
         #self.fields.SetSelection(self.__cur_field)  
791    
792          # calling __SelectField after creating the classGrid fills in the              sizer = wxBoxSizer(wxHORIZONTAL)
793          # grid with the correct information              sizer.Add(wxStaticText(panel, ID_PROPERTY_FIELDTEXT, _("Field: ")),
794          #print "2------------------"                  0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 4)
795          self.fields.SetSelection(self.__cur_field)              sizer.Add(self.fields, 1, wxGROW | wxALL, 4)
         self.__SelectField(self.__cur_field, group = group)  
796    
797          #self.classGrid.SelectGroup(group)              classBox.Add(sizer, 0, wxGROW, 4)
798    
799          controlBox.Add(self.classGrid, 1, wxGROW, 0)              classBox.Add(self.fieldTypeText, 0,
800                            wxGROW | wxALIGN_LEFT | wxALL | wxADJUST_MINSIZE, 4)
801    
802                controlBox = wxBoxSizer(wxHORIZONTAL)
803                controlButtonBox = wxBoxSizer(wxVERTICAL)
804    
805                controlButtonBox.Add(button_gen, 0, wxGROW|wxALL, 4)
806                controlButtonBox.Add(button_add, 0, wxGROW|wxALL, 4)
807                controlButtonBox.Add(button_moveup, 0, wxGROW|wxALL, 4)
808                controlButtonBox.Add(button_movedown, 0, wxGROW|wxALL, 4)
809                controlButtonBox.Add(button_edit, 0, wxGROW|wxALL, 4)
810                controlButtonBox.Add(60, 20, 0, wxGROW|wxALL|wxALIGN_BOTTOM, 4)
811                controlButtonBox.Add(button_remove, 0,
812                                     wxGROW|wxALL|wxALIGN_BOTTOM, 4)
813    
814          controlBox.Add(controlButtonBox, 0, wxGROW, 10)              controlBox.Add(self.classGrid, 1, wxGROW, 0)
815          panelBox.Add(controlBox, 1, wxGROW, 10)              controlBox.Add(controlButtonBox, 0, wxGROW, 10)
816    
817          EVT_BUTTON(self, ID_CLASSIFY_ADD, self._OnAdd)              classBox.Add(controlBox, 1, wxGROW, 10)
818          EVT_BUTTON(self, ID_CLASSIFY_EDITPROPS, self._OnEditGroupProperties)              panelBox.Add(classBox, 1, wxGROW, 0)
         EVT_BUTTON(self, ID_CLASSIFY_REMOVE, self._OnRemove)  
         EVT_BUTTON(self, ID_CLASSIFY_GENCLASS, self._OnGenClass)  
         EVT_BUTTON(self, ID_CLASSIFY_MOVEUP, self._OnMoveUp)  
         EVT_BUTTON(self, ID_CLASSIFY_MOVEDOWN, self._OnMoveDown)  
819    
         ###########  
820    
821          buttonBox = wxBoxSizer(wxHORIZONTAL)          buttonBox = wxBoxSizer(wxHORIZONTAL)
822          buttonBox.Add(wxButton(panel, ID_CLASSIFY_OK, _("OK")),          buttonBox.Add(button_try, 0, wxRIGHT|wxEXPAND, 10)
823                        0, wxALL, 4)          buttonBox.Add(button_revert, 0, wxRIGHT|wxEXPAND, 10)
824          buttonBox.Add(60, 20, 0, wxALL, 4)          buttonBox.Add(button_ok, 0, wxRIGHT|wxEXPAND, 10)
825          buttonBox.Add(wxButton(panel, ID_CLASSIFY_APPLY, _("Apply")),          buttonBox.Add(button_close, 0, wxRIGHT|wxEXPAND, 10)
                       0, wxALL, 4)  
         buttonBox.Add(60, 20, 0, wxALL, 4)  
         buttonBox.Add(wxButton(panel, ID_CLASSIFY_CLOSE, _("Close")),  
                       0, wxALL, 4)  
         buttonBox.Add(60, 20, 0, wxALL, 4)  
         buttonBox.Add(wxButton(panel, ID_CLASSIFY_CANCEL, _("Cancel")),  
                       0, wxALL, 4)  
         panelBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 0)  
   
         EVT_BUTTON(self, ID_CLASSIFY_OK, self._OnOK)  
         EVT_BUTTON(self, ID_CLASSIFY_APPLY, self._OnApply)  
         EVT_BUTTON(self, ID_CLASSIFY_CLOSE, self._OnCloseBtn)  
         EVT_BUTTON(self, ID_CLASSIFY_CANCEL, self._OnCancel)  
   
         ###########  
   
826    
827          panel.SetAutoLayout(True)          panel.SetAutoLayout(True)
828          panel.SetSizer(panelBox)          panel.SetSizer(panelBox)
829            panelBox.Fit(panel)
830          panelBox.SetSizeHints(panel)          panelBox.SetSizeHints(panel)
831    
832          topBox.Add(panel, 1, wxGROW, 0)          topBox.Add(panel, 1, wxGROW | wxALL, 4)
833          panelBox.SetSizeHints(self)          topBox.Add(buttonBox, 0, wxALIGN_RIGHT|wxBOTTOM|wxTOP, 10)
834    
835          self.SetAutoLayout(True)          self.SetAutoLayout(True)
836          self.SetSizer(topBox)          self.SetSizer(topBox)
837            topBox.Fit(self)
838            topBox.SetSizeHints(self)
839            self.Layout()
840    
841            ###########
842    
843            EVT_CHOICE(self, ID_PROPERTY_SELECT, self._OnFieldSelect)
844            EVT_TEXT(self, ID_PROPERTY_TITLE, self._OnTitleChanged)
845            EVT_BUTTON(self, wxID_OK, self._OnOK)
846            EVT_BUTTON(self, ID_PROPERTY_TRY, self._OnTry)
847            EVT_BUTTON(self, wxID_CANCEL, self._OnCloseBtn)
848            EVT_BUTTON(self, ID_PROPERTY_REVERT, self._OnRevert)
849    
850            EVT_BUTTON(self, ID_PROPERTY_ADD, self._OnAdd)
851            EVT_BUTTON(self, ID_PROPERTY_EDITSYM, self._OnEditSymbol)
852            EVT_BUTTON(self, ID_PROPERTY_REMOVE, self._OnRemove)
853            EVT_BUTTON(self, ID_PROPERTY_GENCLASS, self._OnGenClass)
854            EVT_BUTTON(self, ID_PROPERTY_MOVEUP, self._OnMoveUp)
855            EVT_BUTTON(self, ID_PROPERTY_MOVEDOWN, self._OnMoveDown)
856    
         #print "1------------------"  
         #self.Fit()  
857          ######################          ######################
858    
859            text_title.SetFocus()
860          self.haveApplied = False          self.haveApplied = False
861    
862      def EditGroupProperties(self, row):      def unsubscribe_messages(self):
863            self.map.Unsubscribe(MAP_LAYERS_REMOVED, self.map_layers_removed)
864            self.layer.Unsubscribe(LAYER_SHAPESTORE_REPLACED,
865                                   self.layer_shapestore_replaced)
866    
867        def map_layers_removed(self, map):
868            if self.layer not in self.map.Layers():
869                self.Close()
870    
871        def layer_shapestore_replaced(self, *args):
872            self.Close()
873    
874        def EditSymbol(self, row):
875          table = self.classGrid.GetTable()          table = self.classGrid.GetTable()
876          prop = table.GetValueAsCustom(row, COL_SYMBOL, None)          prop = table.GetValueAsCustom(row, COL_SYMBOL, None)
877    
878          # get a new ClassGroupProperties object and copy the          # get a new ClassGroupProperties object and copy the
879          # values over to our current object          # values over to our current object
880          propDlg = SelectPropertiesDialog(NULL, prop, self.layer.ShapeType())          propDlg = SelectPropertiesDialog(self, prop, self.layer.ShapeType())
881    
882            self.Enable(False)
883          if propDlg.ShowModal() == wxID_OK:          if propDlg.ShowModal() == wxID_OK:
884              new_prop = propDlg.GetClassGroupProperties()              new_prop = propDlg.GetClassGroupProperties()
885              table.SetValueAsCustom(row, COL_SYMBOL, None, new_prop)              table.SetValueAsCustom(row, COL_SYMBOL, None, new_prop)
886            self.Enable(True)
887          propDlg.Destroy()          propDlg.Destroy()
888                    
889        def _SetClassification(self, clazz):
890            
891            self.fields.SetClientData(self.__cur_field, clazz)
892            self.classGrid.GetTable().SetClassification(clazz)
893    
894      def __BuildClassification(self, fieldIndex, copyClass = False):      def __BuildClassification(self, fieldIndex, copyClass = False):
895    
# Line 926  class Classifier(NonModalDialog): Line 936  class Classifier(NonModalDialog):
936              fieldType = self.layer.GetFieldType(fieldName)              fieldType = self.layer.GetFieldType(fieldName)
937              clazz.SetFieldType(fieldType)              clazz.SetFieldType(fieldType)
938                                    
         #print "6------------------"  
939          self.classGrid.CreateTable(clazz, self.layer.ShapeType(), group)          self.classGrid.CreateTable(clazz, self.layer.ShapeType(), group)
         #print "7------------------"  
   
   
   
     type2string = {None:             _("None"),  
                    FIELDTYPE_STRING: _("Text"),  
                    FIELDTYPE_INT:    _("Integer"),  
                    FIELDTYPE_DOUBLE: _("Decimal")}  
940    
941      def __SetFieldTypeText(self, fieldIndex):      def __SetFieldTypeText(self, fieldIndex):
942          fieldName = self.fields.GetString(fieldIndex)          fieldName = self.fields.GetString(fieldIndex)
# Line 945  class Classifier(NonModalDialog): Line 946  class Classifier(NonModalDialog):
946    
947          text = Classifier.type2string[fieldType]          text = Classifier.type2string[fieldType]
948    
949          self.fieldTypeText.SetLabel(_("Field Type: %s") % text)          self.fieldTypeText.SetLabel(_("Data Type: %s") % text)
950    
951      def __SelectField(self, newIndex, oldIndex = -1, group = None):      def __SelectField(self, newIndex, oldIndex = -1, group = None):
952          """This method assumes that the current selection for the          """This method assumes that the current selection for the
953          combo has already been set by a call to SetSelection().          combo has already been set by a call to SetSelection().
954          """          """
955    
         #print "3------------------"  
   
956          assert oldIndex >= -1          assert oldIndex >= -1
957    
958          if oldIndex != -1:          if oldIndex != -1:
959              clazz = self.__BuildClassification(oldIndex)              clazz = self.__BuildClassification(oldIndex)
960              self.fields.SetClientData(oldIndex, clazz)              self.fields.SetClientData(oldIndex, clazz)
961    
         #print "4------------------"  
962          self.__SetGridTable(newIndex, group)          self.__SetGridTable(newIndex, group)
         #print "5------------------"  
963    
964          enabled = newIndex != 0          self.__EnableButtons(EB_SELECT_FIELD)
   
         for b in self.controlButtons:  
             b.Enable(enabled)  
965    
966          self.__SetFieldTypeText(newIndex)          self.__SetFieldTypeText(newIndex)
967    
968        def __SetTitle(self, title):
969            if title != "":
970                title = ": " + title
971    
972            self.SetTitle(_("Layer Properties") + title)
973    
974      def _OnEditGroupProperties(self, event):      def _OnEditSymbol(self, event):
975          sel = self.classGrid.GetCurrentSelection()          sel = self.classGrid.GetCurrentSelection()
976    
977          if len(sel) == 1:          if len(sel) == 1:
978              self.EditGroupProperties(sel[0])              self.EditSymbol(sel[0])
979    
980      def _OnFieldSelect(self, event):      def _OnFieldSelect(self, event):
981          index = self.fields.GetSelection()          index = self.fields.GetSelection()
982          self.__SelectField(index, self.__cur_field)          self.__SelectField(index, self.__cur_field)
983          self.__cur_field = index          self.__cur_field = index
984    
985      def _OnApply(self, event):      def _OnTry(self, event):
986          """Put the data from the table into a new Classification and hand          """Put the data from the table into a new Classification and hand
987             it to the layer.             it to the layer.
988          """          """
989    
990          clazz = self.fields.GetClientData(self.__cur_field)          if self.layer.HasClassification():
991                clazz = self.fields.GetClientData(self.__cur_field)
992    
993          #              #
994          # only build the classification if there wasn't one to              # only build the classification if there wasn't one to
995          # to begin with or it has been modified              # to begin with or it has been modified
996          #              #
997          if clazz is None or self.classGrid.GetTable().IsModified():              self.classGrid.SaveEditControlValue()
998              clazz = self.__BuildClassification(self.__cur_field, True)              if clazz is None or self.classGrid.GetTable().IsModified():
999                    clazz = self.__BuildClassification(self.__cur_field, True)
1000    
1001          self.layer.SetClassification(clazz)              self.layer.SetClassification(clazz)
1002    
1003          self.haveApplied = True          self.haveApplied = True
1004    
1005      def _OnOK(self, event):      def _OnOK(self, event):
1006          self._OnApply(event)          self._OnTry(event)
1007          self.Close()          self.Close()
1008    
1009        def OnClose(self, event):
1010            self.unsubscribe_messages()
1011            NonModalNonParentDialog.OnClose(self, event)
1012    
1013      def _OnCloseBtn(self, event):      def _OnCloseBtn(self, event):
1014          """Close is similar to Cancel except that any changes that were          """Close is similar to Cancel except that any changes that were
1015          made and applied remain applied, but the currently displayed          made and applied remain applied, but the currently displayed
# Line 1013  class Classifier(NonModalDialog): Line 1018  class Classifier(NonModalDialog):
1018    
1019          self.Close()          self.Close()
1020    
1021      def _OnCancel(self, event):      def _OnRevert(self, event):
1022          """The layer's current classification stays the same."""          """The layer's current classification stays the same."""
1023          if self.haveApplied:          if self.haveApplied:
1024              self.layer.SetClassification(self.originalClass)              self.layer.SetClassification(self.originalClass)
1025    
1026          self.Close()          #self.Close()
1027    
1028      def _OnAdd(self, event):      def _OnAdd(self, event):
1029          self.classGrid.AppendRows()          self.classGrid.AppendRows()
# Line 1028  class Classifier(NonModalDialog): Line 1033  class Classifier(NonModalDialog):
1033    
1034      def _OnGenClass(self, event):      def _OnGenClass(self, event):
1035    
1036          genDlg = ClassGenDialog(self,          self.genDlg = ClassGenDialog(self, self.layer,
1037                                  self.layer.table,                            self.fields.GetString(self.__cur_field))
1038                                  self.fields.GetString(self.__cur_field))  
1039            EVT_CLOSE(self.genDlg, self._OnGenDialogClose)
1040          if genDlg.ShowModal() == wxID_OK:  
1041              clazz = genDlg.GetClassification()          self.__EnableButtons(EB_GEN_CLASS)
1042              self.fields.SetClientData(self.__cur_field, clazz)  
1043              self.classGrid.GetTable().SetClassification(clazz)          self.genDlg.Show()
1044          genDlg.Destroy()  
1045        def _OnGenDialogClose(self, event):
1046            self.genDlg.Destroy()
1047            self.genDlg = None
1048            self.__EnableButtons(EB_GEN_CLASS)
1049    
1050      def _OnMoveUp(self, event):      def _OnMoveUp(self, event):
1051          sel = self.classGrid.GetCurrentSelection()          sel = self.classGrid.GetCurrentSelection()
1052    
         #print "sel: ", sel  
   
1053          if len(sel) == 1:          if len(sel) == 1:
1054              i = sel[0]              i = sel[0]
1055              if i > 1:              if i > 1:
# Line 1070  class Classifier(NonModalDialog): Line 1077  class Classifier(NonModalDialog):
1077                  self.classGrid.SelectRow(i + 1)                  self.classGrid.SelectRow(i + 1)
1078                  self.classGrid.MakeCellVisible(i + 1, 0)                  self.classGrid.MakeCellVisible(i + 1, 0)
1079    
1080        def _OnTitleChanged(self, event):
1081            obj = event.GetEventObject()
1082    
1083            self.layer.SetTitle(obj.GetValue())
1084            self.__SetTitle(self.layer.Title())
1085    
1086            self.__EnableButtons(EB_LAYER_TITLE)
1087    
1088        def __EnableButtons(self, case):
1089    
1090            list = {wxID_OK                 : True,
1091                    wxID_CANCEL             : True,
1092                    ID_PROPERTY_ADD         : True,
1093                    ID_PROPERTY_MOVEUP      : True,
1094                    ID_PROPERTY_MOVEDOWN    : True,
1095                    ID_PROPERTY_REMOVE      : True,
1096                    ID_PROPERTY_SELECT      : True,
1097                    ID_PROPERTY_FIELDTEXT   : True,
1098                    ID_PROPERTY_GENCLASS    : True,
1099                    ID_PROPERTY_EDITSYM     : True}
1100    
1101            if case == EB_LAYER_TITLE:  
1102                if self.layer.Title() == "":
1103                    list[wxID_OK] = False
1104                    list[wxID_CANCEL] = False
1105    
1106            elif case == EB_SELECT_FIELD:
1107                if self.fields.GetSelection() == 0:
1108                    list[ID_PROPERTY_GENCLASS] = False
1109                    list[ID_PROPERTY_ADD] = False
1110                    list[ID_PROPERTY_MOVEUP] = False
1111                    list[ID_PROPERTY_MOVEDOWN] = False
1112                    list[ID_PROPERTY_REMOVE] = False
1113    
1114            elif case == EB_GEN_CLASS:
1115                if self.genDlg is not None:
1116                    list[ID_PROPERTY_SELECT] = False
1117                    list[ID_PROPERTY_FIELDTEXT] = False
1118                    list[ID_PROPERTY_GENCLASS] = False
1119    
1120            for id, enable in list.items():
1121                win = self.FindWindowById(id)
1122                if win:
1123                    win.Enable(enable)
1124    
 ID_SELPROP_OK = 4001  
 ID_SELPROP_CANCEL = 4002  
1125  ID_SELPROP_SPINCTRL = 4002  ID_SELPROP_SPINCTRL = 4002
1126  ID_SELPROP_PREVIEW = 4003  ID_SELPROP_PREVIEW = 4003
1127  ID_SELPROP_STROKECLR = 4004  ID_SELPROP_STROKECLR = 4004
# Line 1096  class SelectPropertiesDialog(wxDialog): Line 1145  class SelectPropertiesDialog(wxDialog):
1145          previewBox = wxBoxSizer(wxVERTICAL)          previewBox = wxBoxSizer(wxVERTICAL)
1146          previewBox.Add(wxStaticText(self, -1, _("Preview:")),          previewBox.Add(wxStaticText(self, -1, _("Preview:")),
1147              0, wxALIGN_LEFT | wxALL, 4)              0, wxALIGN_LEFT | wxALL, 4)
1148          self.previewWin = ClassDataPreviewWindow(None, self.prop, shapeType,  
1149                                              self, ID_SELPROP_PREVIEW, (40, 40))          self.previewWin = ClassGroupPropertiesCtrl(
1150                self, ID_SELPROP_PREVIEW, self.prop, shapeType,
1151                (40, 40), wxSIMPLE_BORDER)
1152    
1153            self.previewWin.AllowEdit(False)
1154    
1155          previewBox.Add(self.previewWin, 1, wxGROW | wxALL, 4)          previewBox.Add(self.previewWin, 1, wxGROW | wxALL, 4)
1156    
1157          itemBox.Add(previewBox, 1, wxALIGN_LEFT | wxALL | wxGROW, 0)          itemBox.Add(previewBox, 1, wxALIGN_LEFT | wxALL | wxGROW, 0)
# Line 1106  class SelectPropertiesDialog(wxDialog): Line 1160  class SelectPropertiesDialog(wxDialog):
1160          ctrlBox = wxBoxSizer(wxVERTICAL)          ctrlBox = wxBoxSizer(wxVERTICAL)
1161    
1162          lineColorBox = wxBoxSizer(wxHORIZONTAL)          lineColorBox = wxBoxSizer(wxHORIZONTAL)
1163          lineColorBox.Add(          button = wxButton(self, ID_SELPROP_STROKECLR, _("Change Line Color"))
1164              wxButton(self, ID_SELPROP_STROKECLR, _("Change Line Color")),          button.SetFocus()
1165              1, wxALL | wxGROW, 4)          lineColorBox.Add(button, 1, wxALL | wxGROW, 4)
1166          EVT_BUTTON(self, ID_SELPROP_STROKECLR, self._OnChangeLineColor)          EVT_BUTTON(self, ID_SELPROP_STROKECLR, self._OnChangeLineColor)
1167    
1168          lineColorBox.Add(          lineColorBox.Add(
# Line 1154  class SelectPropertiesDialog(wxDialog): Line 1208  class SelectPropertiesDialog(wxDialog):
1208          # Control buttons:          # Control buttons:
1209          #          #
1210          buttonBox = wxBoxSizer(wxHORIZONTAL)          buttonBox = wxBoxSizer(wxHORIZONTAL)
1211          buttonBox.Add(wxButton(self, ID_SELPROP_OK, _("OK")),          button_ok = wxButton(self, wxID_OK, _("OK"))
1212                        0, wxALL, 4)          button_ok.SetDefault()
1213          buttonBox.Add(wxButton(self, ID_SELPROP_CANCEL, _("Cancel")),          buttonBox.Add(button_ok, 0, wxRIGHT|wxEXPAND, 10)
1214                        0, wxALL, 4)          buttonBox.Add(wxButton(self, wxID_CANCEL, _("Cancel")),
1215          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)                        0, wxRIGHT|wxEXPAND, 10)
1216            topBox.Add(buttonBox, 0, wxALIGN_RIGHT|wxBOTTOM|wxTOP, 10)
1217                                                                                                                                                                    
1218          EVT_BUTTON(self, ID_SELPROP_OK, self._OnOK)          #EVT_BUTTON(self, wxID_OK, self._OnOK)
1219          EVT_BUTTON(self, ID_SELPROP_CANCEL, self._OnCancel)          #EVT_BUTTON(self, ID_SELPROP_CANCEL, self._OnCancel)
1220                                                                                                                                                                    
1221          self.SetAutoLayout(True)          self.SetAutoLayout(True)
1222          self.SetSizer(topBox)          self.SetSizer(topBox)
1223          topBox.Fit(self)          topBox.Fit(self)
1224          topBox.SetSizeHints(self)          topBox.SetSizeHints(self)
1225    
1226      def _OnOK(self, event):      def OnOK(self, event):
1227          self.EndModal(wxID_OK)          self.EndModal(wxID_OK)
1228    
1229      def _OnCancel(self, event):      def OnCancel(self, event):
1230          self.EndModal(wxID_CANCEL)          self.EndModal(wxID_CANCEL)
1231    
1232      def _OnSpin(self, event):      def _OnSpin(self, event):
# Line 1229  class ClassDataPreviewWindow(wxWindow): Line 1284  class ClassDataPreviewWindow(wxWindow):
1284          self.shapeType = shapeType          self.shapeType = shapeType
1285          self.previewer = ClassDataPreviewer()          self.previewer = ClassDataPreviewer()
1286    
1287        def GetProperties():
1288            return self.prop
1289    
1290      def _OnPaint(self, event):      def _OnPaint(self, event):
1291          dc = wxPaintDC(self)          dc = wxPaintDC(self)
1292    
# Line 1320  class ClassRenderer(wxPyGridCellRenderer Line 1378  class ClassRenderer(wxPyGridCellRenderer
1378    
1379          dc.DestroyClippingRegion()          dc.DestroyClippingRegion()
1380    
1381    
1382    class ClassGroupPropertiesCtrl(wxWindow, wxControl):
1383    
1384        def __init__(self, parent, id, props, shapeType,
1385                     size = wxDefaultSize, style = 0):
1386    
1387            wxWindow.__init__(self, parent, id, size = size, style = style)
1388    
1389            self.parent = parent
1390    
1391            self.SetProperties(props)
1392            self.SetShapeType(shapeType)
1393            self.AllowEdit(True)
1394    
1395            EVT_PAINT(self, self._OnPaint)
1396            EVT_LEFT_DCLICK(self, self._OnLeftDClick)
1397    
1398            self.previewer = ClassDataPreviewer()
1399    
1400        def _OnPaint(self, event):
1401            dc = wxPaintDC(self)
1402    
1403            # XXX: this doesn't seem to be having an effect:
1404            dc.DestroyClippingRegion()
1405    
1406            w, h = self.GetClientSize()
1407    
1408            self.previewer.Draw(dc,
1409                                wxRect(0, 0, w, h),
1410                                self.GetProperties(),
1411                                self.GetShapeType())
1412    
1413    
1414        def GetProperties(self):
1415            return self.props
1416    
1417        def SetProperties(self, props):
1418            self.props = props
1419            self.Refresh()
1420    
1421        def GetShapeType(self):
1422            return self.shapeType
1423    
1424        def SetShapeType(self, shapeType):
1425            self.shapeType = shapeType
1426            self.Refresh()
1427    
1428        def AllowEdit(self, allow):
1429            self.allowEdit = allow
1430    
1431        def DoEdit(self):
1432            if not self.allowEdit: return
1433    
1434            propDlg = SelectPropertiesDialog(self.parent,
1435                                             self.GetProperties(),
1436                                             self.GetShapeType())
1437    
1438            if propDlg.ShowModal() == wxID_OK:
1439                new_prop = propDlg.GetClassGroupProperties()
1440                self.SetProperties(new_prop)
1441                self.Refresh()
1442    
1443            propDlg.Destroy()
1444    
1445        def _OnLeftDClick(self, event):
1446            self.DoEdit()

Legend:
Removed from v.615  
changed lines
  Added in v.1307

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26