/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/classifier.py
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/Thuban/UI/classifier.py

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

revision 650 by jonathan, Fri Apr 11 14:27:41 2003 UTC revision 1464 by bh, Fri Jul 18 18:20:40 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 Transparent
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    from messages import MAP_REPLACED
39    
40  ID_CLASS_TABLE = 40011  ID_CLASS_TABLE = 40011
41    
# Line 63  class ClassGrid(wxGrid): Line 69  class ClassGrid(wxGrid):
69                   use for display.                   use for display.
70          """          """
71    
72          wxGrid.__init__(self, parent, ID_CLASS_TABLE)          wxGrid.__init__(self, parent, ID_CLASS_TABLE, style = 0)
73    
74          self.classifier = classifier          self.classifier = classifier
75    
# Line 79  class ClassGrid(wxGrid): Line 85  class ClassGrid(wxGrid):
85          #print "GetCellAttr ", row, col          #print "GetCellAttr ", row, col
86          #wxGrid.GetCellAttr(self, row, col)          #wxGrid.GetCellAttr(self, row, col)
87    
88      def CreateTable(self, clazz, shapeType, group = None):      def CreateTable(self, clazz, fieldType, shapeType, group = None):
89    
90          assert isinstance(clazz, Classification)          assert isinstance(clazz, Classification)
91    
# Line 99  class ClassGrid(wxGrid): Line 105  class ClassGrid(wxGrid):
105          self.SetSelectionMode(wxGrid.wxGridSelectRows)          self.SetSelectionMode(wxGrid.wxGridSelectRows)
106          self.ClearSelection()          self.ClearSelection()
107    
108          table.Reset(clazz, shapeType, group)          table.Reset(clazz, fieldType, shapeType, group)
109    
110      def GetCurrentSelection(self):      def GetCurrentSelection(self):
111          """Return the currently highlighted rows as an increasing list          """Return the currently highlighted rows as an increasing list
# Line 244  class ClassGrid(wxGrid): Line 250  class ClassGrid(wxGrid):
250    
251      def _OnCellResize(self, event):      def _OnCellResize(self, event):
252          self.FitInside()          self.FitInside()
253            event.Skip()
254    
255  class ClassTable(wxPyGridTableBase):  class ClassTable(wxPyGridTableBase):
256      """Represents the underlying data structure for the grid."""      """Represents the underlying data structure for the grid."""
# Line 252  class ClassTable(wxPyGridTableBase): Line 259  class ClassTable(wxPyGridTableBase):
259    
260    
261      def __init__(self, view = None):      def __init__(self, view = None):
     #def __init__(self, clazz, shapeType, view = None):  
262          """Constructor.          """Constructor.
263    
264          shapeType -- the type of shape that the layer uses          shapeType -- the type of shape that the layer uses
# Line 269  class ClassTable(wxPyGridTableBase): Line 275  class ClassTable(wxPyGridTableBase):
275    
276          self.SetView(view)          self.SetView(view)
277    
278      def Reset(self, clazz, shapeType, group = None):      def Reset(self, clazz, fieldType, shapeType, group = None):
279          """Reset the table with the given data.          """Reset the table with the given data.
280    
281          This is necessary because wxWindows does not allow a grid's          This is necessary because wxWindows does not allow a grid's
# Line 287  class ClassTable(wxPyGridTableBase): Line 293  class ClassTable(wxPyGridTableBase):
293    
294          self.GetView().BeginBatch()          self.GetView().BeginBatch()
295    
296          self.fieldType = clazz.GetFieldType()          self.fieldType = fieldType
297          self.shapeType = shapeType          self.shapeType = shapeType
298    
299          self.SetClassification(clazz, group)          self.SetClassification(clazz, group)
# Line 398  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 458  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 in (FIELDTYPE_INT, 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 556  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 650  class ClassTable(wxPyGridTableBase): Line 648  class ClassTable(wxPyGridTableBase):
648              self.__NotifyRowChanges(old_len, self.GetNumberRows())              self.__NotifyRowChanges(old_len, self.GetNumberRows())
649    
650    
 ID_PROPERTY_OK = 4001  
651  ID_PROPERTY_REVERT = 4002  ID_PROPERTY_REVERT = 4002
652  ID_PROPERTY_ADD = 4003  ID_PROPERTY_ADD = 4003
653  ID_PROPERTY_GENCLASS = 4004  ID_PROPERTY_GENCLASS = 4004
# Line 659  ID_PROPERTY_MOVEUP = 4006 Line 656  ID_PROPERTY_MOVEUP = 4006
656  ID_PROPERTY_MOVEDOWN = 4007  ID_PROPERTY_MOVEDOWN = 4007
657  ID_PROPERTY_TRY = 4008  ID_PROPERTY_TRY = 4008
658  ID_PROPERTY_EDITSYM = 4009  ID_PROPERTY_EDITSYM = 4009
 ID_PROPERTY_CLOSE = 4010  
659  ID_PROPERTY_SELECT = 4011  ID_PROPERTY_SELECT = 4011
660  ID_PROPERTY_TITLE = 4012  ID_PROPERTY_TITLE = 4012
661  ID_PROPERTY_FIELDTEXT = 4013  ID_PROPERTY_FIELDTEXT = 4013
# Line 675  EB_LAYER_TITLE = 0 Line 671  EB_LAYER_TITLE = 0
671  EB_SELECT_FIELD = 1  EB_SELECT_FIELD = 1
672  EB_GEN_CLASS = 2  EB_GEN_CLASS = 2
673    
674  class Classifier(NonModalDialog):  class Classifier(NonModalNonParentDialog):
675    
676      type2string = {None:             _("None"),      type2string = {None:             _("None"),
677                     FIELDTYPE_STRING: _("Text"),                     FIELDTYPE_STRING: _("Text"),
678                     FIELDTYPE_INT:    _("Integer"),                     FIELDTYPE_INT:    _("Integer"),
679                     FIELDTYPE_DOUBLE: _("Decimal")}                     FIELDTYPE_DOUBLE: _("Decimal")}
680    
681      def __init__(self, parent, name, layer, group = None):      def __init__(self, parent, name, map, layer, group = None):
682          NonModalDialog.__init__(self, parent, name, "")          NonModalNonParentDialog.__init__(self, parent, name, "")
683    
684          self.__SetTitle(layer.Title())          self.__SetTitle(layer.Title())
685    
686            self.parent.Subscribe(MAP_REPLACED, self.map_replaced)
687          self.layer = layer          self.layer = layer
688            self.map = map
689    
690          self.originalClass = self.layer.GetClassification()          self.map.Subscribe(MAP_LAYERS_REMOVED, self.map_layers_removed)
691          field = self.originalClass.GetField()          self.layer.Subscribe(LAYER_SHAPESTORE_REPLACED,
692          fieldType = self.originalClass.GetFieldType()                               self.layer_shapestore_replaced)
693    
694          self.genDlg = None          self.genDlg = None
695    
696          topBox = wxBoxSizer(wxVERTICAL)          ############################
697            # Create the controls
698          sizer = wxBoxSizer(wxHORIZONTAL)          #
         sizer.Add(wxStaticText(self, -1, _("Title: ")),  
             0, wxALIGN_LEFT | wxALL | wxALIGN_CENTER_VERTICAL, 4)  
         sizer.Add(wxTextCtrl(self, ID_PROPERTY_TITLE, layer.Title()),  
                   1, wxGROW | wxALL, 4)  
         EVT_TEXT(self, ID_PROPERTY_TITLE, self._OnTitleChanged)  
   
         topBox.Add(sizer, 0, wxGROW, 4)  
   
         topBox.Add(wxStaticText(self, -1,  
                                 _("Type: %s") % layer.ShapeType()),  
             0, wxALIGN_LEFT | wxALL, 4)  
   
         panel = wxPanel(self, -1, size=(100, 100))  
   
         #####################  
699    
700          #panelBox = wxBoxSizer(wxVERTICAL)          panel = wxPanel(self, -1)
         panelBox = wxStaticBoxSizer(  
                     wxStaticBox(panel, -1, _("Classification")), wxVERTICAL)  
701    
702            text_title = wxTextCtrl(panel, ID_PROPERTY_TITLE, layer.Title())
703            self.fieldTypeText = wxStaticText(panel, -1, "")
704    
705          #          if layer.HasClassification():
706          # make field combo box              self.originalClass = self.layer.GetClassification()
707          #              self.originalClassField = self.layer.GetClassificationColumn()
708          self.fields = wxComboBox(panel, ID_PROPERTY_SELECT, "",              field = self.originalClassField
709                                       style = wxCB_READONLY)              fieldType = self.layer.GetFieldType(field)
710    
711          self.num_cols = layer.table.field_count()              table = layer.ShapeStore().Table()
712          # just assume the first field in case one hasn't been              #
713          # specified in the file.              # make field choice box
714          self.__cur_field = 0              #
715                self.fields = wxChoice(panel, ID_PROPERTY_SELECT,)
716    
717          self.fields.Append("<None>")              self.num_cols = table.NumColumns()
718                # just assume the first field in case one hasn't been
719                # specified in the file.
720                self.__cur_field = 0
721    
722          if self.originalClass.GetFieldType() is None:              self.fields.Append("<None>")
             self.fields.SetClientData(0, copy.deepcopy(self.originalClass))  
         else:  
             self.fields.SetClientData(0, None)  
723    
724          for i in range(self.num_cols):              if fieldType is None:
725              type, name, len, decc = layer.table.field_info(i)                  self.fields.SetClientData(0, copy.deepcopy(self.originalClass))
             self.fields.Append(name)  
   
             if name == field:  
                 self.__cur_field = i + 1  
                 self.fields.SetClientData(i + 1,  
                                           copy.deepcopy(self.originalClass))  
726              else:              else:
727                  self.fields.SetClientData(i + 1, None)                  self.fields.SetClientData(0, None)
728    
729                for i in range(self.num_cols):
730                    name = table.Column(i).name
731                    self.fields.Append(name)
732    
733                    if name == field:
734                        self.__cur_field = i + 1
735                        self.fields.SetClientData(i + 1,
736                                                  copy.deepcopy(self.originalClass))
737                    else:
738                        self.fields.SetClientData(i + 1, None)
739    
740          ###########              button_gen = wxButton(panel, ID_PROPERTY_GENCLASS,
741                    _("Generate Class"))
742                button_add = wxButton(panel, ID_PROPERTY_ADD,
743                    _("Add"))
744                button_moveup = wxButton(panel, ID_PROPERTY_MOVEUP,
745                    _("Move Up"))
746                button_movedown = wxButton(panel, ID_PROPERTY_MOVEDOWN,
747                    _("Move Down"))
748                button_edit = wxButton(panel, ID_PROPERTY_EDITSYM,
749                    _("Edit Symbol"))
750                button_remove = wxButton(panel, ID_PROPERTY_REMOVE,
751                    _("Remove"))
752    
753                self.classGrid = ClassGrid(panel, self)
754    
755                # calling __SelectField after creating the classGrid fills in the
756                # grid with the correct information
757                self.fields.SetSelection(self.__cur_field)
758                self.__SelectField(self.__cur_field, group = group)
759    
760            button_try = wxButton(self, ID_PROPERTY_TRY, _("Try"))
761            button_revert = wxButton(self, ID_PROPERTY_REVERT, _("Revert"))
762            button_ok = wxButton(self, wxID_OK, _("OK"))
763            button_close = wxButton(self, wxID_CANCEL, _("Close"))
764            button_ok.SetDefault()
765    
766            ############################
767            # Layout the controls
768            #
769    
770            topBox = wxBoxSizer(wxVERTICAL)
771            panelBox = wxBoxSizer(wxVERTICAL)
772    
773          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wxBoxSizer(wxHORIZONTAL)
774          sizer.Add(wxStaticText(panel, ID_PROPERTY_FIELDTEXT, _("Field: ")),          sizer.Add(wxStaticText(panel, -1, _("Title: ")),
775              0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 4)              0, wxALIGN_LEFT | wxALL | wxALIGN_CENTER_VERTICAL, 4)
776          sizer.Add(self.fields, 1, wxGROW | wxALL, 4)          sizer.Add(text_title, 1, wxGROW, 0)
         EVT_COMBOBOX(self, ID_PROPERTY_SELECT, self._OnFieldSelect)  
777    
778          panelBox.Add(sizer, 0, wxGROW, 4)          panelBox.Add(sizer, 0, wxGROW, 4)
779    
780          self.fieldTypeText = wxStaticText(panel, -1, "")          if isinstance(layer, RasterLayer):
781          panelBox.Add(self.fieldTypeText, 0,              type = "Image"
782                       wxGROW | wxALIGN_LEFT | wxALL | wxADJUST_MINSIZE, 4)          else:
783                type = layer.ShapeType()
784    
785            panelBox.Add(wxStaticText(panel, -1, _("Type: %s") % type),
786                0, wxALIGN_LEFT | wxALL, 4)
787    
788          #          if layer.HasClassification():
         # Control Box  
         #  
         controlBox = wxBoxSizer(wxHORIZONTAL)  
789    
790                classBox = wxStaticBoxSizer(
791                            wxStaticBox(panel, -1, _("Classification")), wxVERTICAL)
792    
         ###########  
         #  
         # Control buttons:  
         #  
         controlButtonBox = wxBoxSizer(wxVERTICAL)  
793    
794          button = wxButton(panel, ID_PROPERTY_GENCLASS, _("Generate Class"))              sizer = wxBoxSizer(wxHORIZONTAL)
795          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)              sizer.Add(wxStaticText(panel, ID_PROPERTY_FIELDTEXT, _("Field: ")),
796                    0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 4)
797                sizer.Add(self.fields, 1, wxGROW | wxALL, 4)
798    
799          button = wxButton(panel, ID_PROPERTY_ADD, _("Add"))              classBox.Add(sizer, 0, wxGROW, 4)
         controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)  
800    
801          button = wxButton(panel, ID_PROPERTY_MOVEUP, _("Move Up"))              classBox.Add(self.fieldTypeText, 0,
802          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)                          wxGROW | wxALIGN_LEFT | wxALL | wxADJUST_MINSIZE, 4)
803    
804          button = wxButton(panel, ID_PROPERTY_MOVEDOWN, _("Move Down"))              controlBox = wxBoxSizer(wxHORIZONTAL)
805          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)              controlButtonBox = wxBoxSizer(wxVERTICAL)
806    
807          button = wxButton(panel, ID_PROPERTY_EDITSYM, _("Edit Symbol"))              controlButtonBox.Add(button_gen, 0, wxGROW|wxALL, 4)
808          controlButtonBox.Add(button, 0, wxGROW | wxALL, 4)              controlButtonBox.Add(button_add, 0, wxGROW|wxALL, 4)
809                controlButtonBox.Add(button_moveup, 0, wxGROW|wxALL, 4)
810                controlButtonBox.Add(button_movedown, 0, wxGROW|wxALL, 4)
811                controlButtonBox.Add(button_edit, 0, wxGROW|wxALL, 4)
812                controlButtonBox.Add(60, 20, 0, wxGROW|wxALL|wxALIGN_BOTTOM, 4)
813                controlButtonBox.Add(button_remove, 0,
814                                     wxGROW|wxALL|wxALIGN_BOTTOM, 4)
815    
816          controlButtonBox.Add(60, 20, 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)              controlBox.Add(self.classGrid, 1, wxGROW, 0)
817                controlBox.Add(controlButtonBox, 0, wxGROW, 10)
818    
819          button = wxButton(panel, ID_PROPERTY_REMOVE, _("Remove"))              classBox.Add(controlBox, 1, wxGROW, 10)
820          controlButtonBox.Add(button, 0, wxGROW | wxALL | wxALIGN_BOTTOM, 4)              panelBox.Add(classBox, 1, wxGROW, 0)
821    
822    
823          ###########          buttonBox = wxBoxSizer(wxHORIZONTAL)
824          #          buttonBox.Add(button_try, 0, wxRIGHT|wxEXPAND, 10)
825          # Classification data table          buttonBox.Add(button_revert, 0, wxRIGHT|wxEXPAND, 10)
826          #          buttonBox.Add(button_ok, 0, wxRIGHT|wxEXPAND, 10)
827            buttonBox.Add(button_close, 0, wxRIGHT|wxEXPAND, 10)
828    
829          self.classGrid = ClassGrid(panel, self)          panel.SetAutoLayout(True)
830            panel.SetSizer(panelBox)
831            panelBox.Fit(panel)
832            panelBox.SetSizeHints(panel)
833    
834          # calling __SelectField after creating the classGrid fills in the          topBox.Add(panel, 1, wxGROW | wxALL, 4)
835          # grid with the correct information          topBox.Add(buttonBox, 0, wxALIGN_RIGHT|wxBOTTOM|wxTOP, 10)
         self.fields.SetSelection(self.__cur_field)  
         self.__SelectField(self.__cur_field, group = group)  
836    
837          controlBox.Add(self.classGrid, 1, wxGROW, 0)          self.SetAutoLayout(True)
838            self.SetSizer(topBox)
839            topBox.Fit(self)
840            topBox.SetSizeHints(self)
841            self.Layout()
842    
843          controlBox.Add(controlButtonBox, 0, wxGROW, 10)          ###########
844          panelBox.Add(controlBox, 1, wxGROW, 10)  
845            EVT_CHOICE(self, ID_PROPERTY_SELECT, self._OnFieldSelect)
846            EVT_TEXT(self, ID_PROPERTY_TITLE, self._OnTitleChanged)
847            EVT_BUTTON(self, wxID_OK, self._OnOK)
848            EVT_BUTTON(self, ID_PROPERTY_TRY, self._OnTry)
849            EVT_BUTTON(self, wxID_CANCEL, self._OnCloseBtn)
850            EVT_BUTTON(self, ID_PROPERTY_REVERT, self._OnRevert)
851    
852          EVT_BUTTON(self, ID_PROPERTY_ADD, self._OnAdd)          EVT_BUTTON(self, ID_PROPERTY_ADD, self._OnAdd)
853          EVT_BUTTON(self, ID_PROPERTY_EDITSYM, self._OnEditSymbol)          EVT_BUTTON(self, ID_PROPERTY_EDITSYM, self._OnEditSymbol)
# Line 822  class Classifier(NonModalDialog): Line 856  class Classifier(NonModalDialog):
856          EVT_BUTTON(self, ID_PROPERTY_MOVEUP, self._OnMoveUp)          EVT_BUTTON(self, ID_PROPERTY_MOVEUP, self._OnMoveUp)
857          EVT_BUTTON(self, ID_PROPERTY_MOVEDOWN, self._OnMoveDown)          EVT_BUTTON(self, ID_PROPERTY_MOVEDOWN, self._OnMoveDown)
858    
859          ###########          ######################
   
         panel.SetAutoLayout(True)  
         panel.SetSizer(panelBox)  
         panelBox.SetSizeHints(panel)  
   
         topBox.Add(panel, 1, wxGROW | wxALL, 4)  
   
         ###########  
   
         buttonBox = wxBoxSizer(wxHORIZONTAL)  
         buttonBox.Add(wxButton(self, ID_PROPERTY_TRY, _("Try")),  
                       0, wxALL, 4)  
         buttonBox.Add(60, 20, 0, wxALL, 4)  
         buttonBox.Add(wxButton(self, ID_PROPERTY_REVERT, _("Revert")),  
                       0, wxALL, 4)  
         buttonBox.Add(60, 20, 0, wxALL, 4)  
         buttonBox.Add(wxButton(self, ID_PROPERTY_OK, _("OK")),  
                       0, wxALL, 4)  
         buttonBox.Add(60, 20, 0, wxALL, 4)  
         buttonBox.Add(wxButton(self, ID_PROPERTY_CLOSE, _("Close")),  
                       0, wxALL, 4)  
         topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 0)  
860    
861          EVT_BUTTON(self, ID_PROPERTY_OK, self._OnOK)          text_title.SetFocus()
862          EVT_BUTTON(self, ID_PROPERTY_TRY, self._OnTry)          self.haveApplied = False
         EVT_BUTTON(self, ID_PROPERTY_CLOSE, self._OnCloseBtn)  
         EVT_BUTTON(self, ID_PROPERTY_REVERT, self._OnRevert)  
863    
864          ###########      def unsubscribe_messages(self):
865            self.parent.Unsubscribe(MAP_REPLACED, self.map_replaced)
866            self.map.Unsubscribe(MAP_LAYERS_REMOVED, self.map_layers_removed)
867            self.layer.Unsubscribe(LAYER_SHAPESTORE_REPLACED,
868                                   self.layer_shapestore_replaced)
869    
870        def map_layers_removed(self, map):
871            if self.layer not in self.map.Layers():
872                self.Close()
873    
874          topBox.SetSizeHints(self)      def layer_shapestore_replaced(self, *args):
875          self.SetAutoLayout(True)          """Subscribed to the map's LAYER_SHAPESTORE_REPLACED message.
         self.SetSizer(topBox)  
876    
877          #self.Fit()          Close self.
878          ######################          """
879            self.Close()
880    
881          self.haveApplied = False      def map_replaced(self, *args):
882            """Subscribed to the mainwindow's MAP_REPLACED message. Close self."""
883            self.Close()
884    
885      def EditSymbol(self, row):      def EditSymbol(self, row):
886          table = self.classGrid.GetTable()          table = self.classGrid.GetTable()
# Line 868  class Classifier(NonModalDialog): Line 888  class Classifier(NonModalDialog):
888    
889          # get a new ClassGroupProperties object and copy the          # get a new ClassGroupProperties object and copy the
890          # values over to our current object          # values over to our current object
891          propDlg = SelectPropertiesDialog(NULL, prop, self.layer.ShapeType())          propDlg = SelectPropertiesDialog(self, prop, self.layer.ShapeType())
892    
893          self.Enable(False)          self.Enable(False)
894          if propDlg.ShowModal() == wxID_OK:          if propDlg.ShowModal() == wxID_OK:
# Line 882  class Classifier(NonModalDialog): Line 902  class Classifier(NonModalDialog):
902          self.fields.SetClientData(self.__cur_field, clazz)          self.fields.SetClientData(self.__cur_field, clazz)
903          self.classGrid.GetTable().SetClassification(clazz)          self.classGrid.GetTable().SetClassification(clazz)
904    
905      def __BuildClassification(self, fieldIndex, copyClass = False):      def __BuildClassification(self, fieldIndex, copyClass=False, force=False):
906    
907  #       numRows = self.classGrid.GetNumberRows()  #       numRows = self.classGrid.GetNumberRows()
908  #       assert numRows > 0  # there should always be a default row  #       assert numRows > 0  # there should always be a default row
909    
 #       clazz = Classification()  
910          if fieldIndex == 0:          if fieldIndex == 0:
911              fieldName = None              fieldName = None
912              fieldType = None              fieldType = None
# Line 895  class Classifier(NonModalDialog): Line 914  class Classifier(NonModalDialog):
914              fieldName = self.fields.GetString(fieldIndex)              fieldName = self.fields.GetString(fieldIndex)
915              fieldType = self.layer.GetFieldType(fieldName)              fieldType = self.layer.GetFieldType(fieldName)
916    
917          clazz = self.classGrid.GetTable().GetClassification()          clazz = self.fields.GetClientData(fieldIndex)
918            if clazz is None or self.classGrid.GetTable().IsModified() or force:
919          if copyClass:              clazz = self.classGrid.GetTable().GetClassification()
920              clazz = copy.deepcopy(clazz)              if copyClass:
921                    clazz = copy.deepcopy(clazz)
         clazz.SetField(fieldName)  
         clazz.SetFieldType(fieldType)  
   
   
 #       table = self.classGrid.GetTable()  
 #       clazz.SetDefaultGroup(table.GetClassGroup(0))  
   
 #       for i in range(1, numRows):  
 #           clazz.AppendGroup(table.GetClassGroup(i))  
922    
923          return clazz          return clazz, fieldName
924    
925      def __SetGridTable(self, fieldIndex, group = None):      def __SetGridTable(self, fieldIndex, group = None):
926    
# Line 923  class Classifier(NonModalDialog): Line 933  class Classifier(NonModalDialog):
933                      self.layer.GetClassification().                      self.layer.GetClassification().
934                                 GetDefaultGroup().GetProperties()))                                 GetDefaultGroup().GetProperties()))
935    
936              fieldName = self.fields.GetString(fieldIndex)          fieldName = self.fields.GetString(fieldIndex)
937              fieldType = self.layer.GetFieldType(fieldName)          fieldType = self.layer.GetFieldType(fieldName)
             clazz.SetFieldType(fieldType)  
938                                    
939          self.classGrid.CreateTable(clazz, self.layer.ShapeType(), group)          self.classGrid.CreateTable(clazz, fieldType,
940                                       self.layer.ShapeType(), group)
941    
942      def __SetFieldTypeText(self, fieldIndex):      def __SetFieldTypeText(self, fieldIndex):
943          fieldName = self.fields.GetString(fieldIndex)          fieldName = self.fields.GetString(fieldIndex)
# Line 947  class Classifier(NonModalDialog): Line 957  class Classifier(NonModalDialog):
957          assert oldIndex >= -1          assert oldIndex >= -1
958    
959          if oldIndex != -1:          if oldIndex != -1:
960              clazz = self.__BuildClassification(oldIndex)              clazz, name = self.__BuildClassification(oldIndex, force = True)
961              self.fields.SetClientData(oldIndex, clazz)              self.fields.SetClientData(oldIndex, clazz)
962    
963          self.__SetGridTable(newIndex, group)          self.__SetGridTable(newIndex, group)
964    
965          self.__EnableButtons(EB_SELECT_FIELD, newIndex != 0)          self.__EnableButtons(EB_SELECT_FIELD)
966    
967          self.__SetFieldTypeText(newIndex)          self.__SetFieldTypeText(newIndex)
968    
# Line 978  class Classifier(NonModalDialog): Line 988  class Classifier(NonModalDialog):
988             it to the layer.             it to the layer.
989          """          """
990    
991          clazz = self.fields.GetClientData(self.__cur_field)          if self.layer.HasClassification():
992                clazz = self.fields.GetClientData(self.__cur_field)
993    
994          #              #
995          # only build the classification if there wasn't one to              # only build the classification if there wasn't one to
996          # to begin with or it has been modified              # to begin with or it has been modified
997          #              #
998          if clazz is None or self.classGrid.GetTable().IsModified():              self.classGrid.SaveEditControlValue()
999              clazz = self.__BuildClassification(self.__cur_field, True)              clazz, name = self.__BuildClassification(self.__cur_field, True)
1000    
1001          self.layer.SetClassification(clazz)              self.layer.SetClassificationColumn(name)
1002                self.layer.SetClassification(clazz)
1003    
1004          self.haveApplied = True          self.haveApplied = True
1005    
# Line 995  class Classifier(NonModalDialog): Line 1007  class Classifier(NonModalDialog):
1007          self._OnTry(event)          self._OnTry(event)
1008          self.Close()          self.Close()
1009    
1010        def OnClose(self, event):
1011            self.unsubscribe_messages()
1012            NonModalNonParentDialog.OnClose(self, event)
1013    
1014      def _OnCloseBtn(self, event):      def _OnCloseBtn(self, event):
1015          """Close is similar to Cancel except that any changes that were          """Close is similar to Cancel except that any changes that were
1016          made and applied remain applied, but the currently displayed          made and applied remain applied, but the currently displayed
# Line 1006  class Classifier(NonModalDialog): Line 1022  class Classifier(NonModalDialog):
1022      def _OnRevert(self, event):      def _OnRevert(self, event):
1023          """The layer's current classification stays the same."""          """The layer's current classification stays the same."""
1024          if self.haveApplied:          if self.haveApplied:
1025                self.layer.SetClassificationColumn(self.originalClassField)
1026              self.layer.SetClassification(self.originalClass)              self.layer.SetClassification(self.originalClass)
1027    
1028          #self.Close()          #self.Close()
# Line 1023  class Classifier(NonModalDialog): Line 1040  class Classifier(NonModalDialog):
1040    
1041          EVT_CLOSE(self.genDlg, self._OnGenDialogClose)          EVT_CLOSE(self.genDlg, self._OnGenDialogClose)
1042    
1043          self.__EnableButtons(EB_GEN_CLASS, False)          self.__EnableButtons(EB_GEN_CLASS)
1044    
1045          self.genDlg.Show()          self.genDlg.Show()
1046    
1047      def _OnGenDialogClose(self, event):      def _OnGenDialogClose(self, event):
1048          self.genDlg.Destroy()          self.genDlg.Destroy()
1049          self.__EnableButtons(EB_GEN_CLASS, True)          self.genDlg = None
1050            self.__EnableButtons(EB_GEN_CLASS)
1051    
1052      def _OnMoveUp(self, event):      def _OnMoveUp(self, event):
1053          sel = self.classGrid.GetCurrentSelection()          sel = self.classGrid.GetCurrentSelection()
# Line 1067  class Classifier(NonModalDialog): Line 1085  class Classifier(NonModalDialog):
1085          self.layer.SetTitle(obj.GetValue())          self.layer.SetTitle(obj.GetValue())
1086          self.__SetTitle(self.layer.Title())          self.__SetTitle(self.layer.Title())
1087    
1088          self.__EnableButtons(EB_LAYER_TITLE, self.layer.Title() != "")          self.__EnableButtons(EB_LAYER_TITLE)
1089    
1090        def __EnableButtons(self, case):
1091    
1092      def __EnableButtons(self, case, enable):          list = {wxID_OK                 : True,
1093                    wxID_CANCEL             : True,
1094                    ID_PROPERTY_ADD         : True,
1095                    ID_PROPERTY_MOVEUP      : True,
1096                    ID_PROPERTY_MOVEDOWN    : True,
1097                    ID_PROPERTY_REMOVE      : True,
1098                    ID_PROPERTY_SELECT      : True,
1099                    ID_PROPERTY_FIELDTEXT   : True,
1100                    ID_PROPERTY_GENCLASS    : True,
1101                    ID_PROPERTY_EDITSYM     : True}
1102    
1103          if case == EB_LAYER_TITLE:            if case == EB_LAYER_TITLE:  
1104              list = (ID_PROPERTY_OK,              if self.layer.Title() == "":
1105                      ID_PROPERTY_CLOSE)                  list[wxID_OK] = False
1106                    list[wxID_CANCEL] = False
1107    
1108          elif case == EB_SELECT_FIELD:          elif case == EB_SELECT_FIELD:
1109              list = (ID_PROPERTY_GENCLASS,              if self.fields.GetSelection() == 0:
1110                      ID_PROPERTY_ADD,                  list[ID_PROPERTY_GENCLASS] = False
1111                      ID_PROPERTY_MOVEUP,                  list[ID_PROPERTY_ADD] = False
1112                      ID_PROPERTY_MOVEDOWN,                  list[ID_PROPERTY_MOVEUP] = False
1113                      ID_PROPERTY_EDITSYM,                  list[ID_PROPERTY_MOVEDOWN] = False
1114                      ID_PROPERTY_REMOVE)                  list[ID_PROPERTY_REMOVE] = False
1115    
1116          elif case == EB_GEN_CLASS:          elif case == EB_GEN_CLASS:
1117              list = (ID_PROPERTY_SELECT,              if self.genDlg is not None:
1118                      ID_PROPERTY_FIELDTEXT,                  list[ID_PROPERTY_SELECT] = False
1119                      ID_PROPERTY_GENCLASS,                  list[ID_PROPERTY_FIELDTEXT] = False
1120                      ID_PROPERTY_EDITSYM)                  list[ID_PROPERTY_GENCLASS] = False
1121    
1122            for id, enable in list.items():
1123                win = self.FindWindowById(id)
1124                if win:
1125                    win.Enable(enable)
1126    
         for id in list:  
             self.FindWindowById(id).Enable(enable)  
   
 ID_SELPROP_OK = 4001  
 ID_SELPROP_CANCEL = 4002  
1127  ID_SELPROP_SPINCTRL = 4002  ID_SELPROP_SPINCTRL = 4002
1128  ID_SELPROP_PREVIEW = 4003  ID_SELPROP_PREVIEW = 4003
1129  ID_SELPROP_STROKECLR = 4004  ID_SELPROP_STROKECLR = 4004
# Line 1132  class SelectPropertiesDialog(wxDialog): Line 1162  class SelectPropertiesDialog(wxDialog):
1162          ctrlBox = wxBoxSizer(wxVERTICAL)          ctrlBox = wxBoxSizer(wxVERTICAL)
1163    
1164          lineColorBox = wxBoxSizer(wxHORIZONTAL)          lineColorBox = wxBoxSizer(wxHORIZONTAL)
1165          lineColorBox.Add(          button = wxButton(self, ID_SELPROP_STROKECLR, _("Change Line Color"))
1166              wxButton(self, ID_SELPROP_STROKECLR, _("Change Line Color")),          button.SetFocus()
1167              1, wxALL | wxGROW, 4)          lineColorBox.Add(button, 1, wxALL | wxGROW, 4)
1168          EVT_BUTTON(self, ID_SELPROP_STROKECLR, self._OnChangeLineColor)          EVT_BUTTON(self, ID_SELPROP_STROKECLR, self._OnChangeLineColor)
1169    
1170          lineColorBox.Add(          lineColorBox.Add(
# Line 1180  class SelectPropertiesDialog(wxDialog): Line 1210  class SelectPropertiesDialog(wxDialog):
1210          # Control buttons:          # Control buttons:
1211          #          #
1212          buttonBox = wxBoxSizer(wxHORIZONTAL)          buttonBox = wxBoxSizer(wxHORIZONTAL)
1213          buttonBox.Add(wxButton(self, ID_SELPROP_OK, _("OK")),          button_ok = wxButton(self, wxID_OK, _("OK"))
1214                        0, wxALL, 4)          buttonBox.Add(button_ok, 0, wxRIGHT|wxEXPAND, 10)
1215          buttonBox.Add(wxButton(self, ID_SELPROP_CANCEL, _("Cancel")),          buttonBox.Add(wxButton(self, wxID_CANCEL, _("Cancel")),
1216                        0, wxALL, 4)                        0, wxRIGHT|wxEXPAND, 10)
1217          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)          topBox.Add(buttonBox, 0, wxALIGN_RIGHT|wxBOTTOM|wxTOP, 10)
1218    
1219            button_ok.SetDefault()
1220                                                                                                                                                                    
1221          EVT_BUTTON(self, ID_SELPROP_OK, self._OnOK)          #EVT_BUTTON(self, wxID_OK, self._OnOK)
1222          EVT_BUTTON(self, ID_SELPROP_CANCEL, self._OnCancel)          #EVT_BUTTON(self, ID_SELPROP_CANCEL, self._OnCancel)
1223                                                                                                                                                                    
1224          self.SetAutoLayout(True)          self.SetAutoLayout(True)
1225          self.SetSizer(topBox)          self.SetSizer(topBox)
1226          topBox.Fit(self)          topBox.Fit(self)
1227          topBox.SetSizeHints(self)          topBox.SetSizeHints(self)
1228    
1229      def _OnOK(self, event):      def OnOK(self, event):
1230          self.EndModal(wxID_OK)          self.EndModal(wxID_OK)
1231    
1232      def _OnCancel(self, event):      def OnCancel(self, event):
1233          self.EndModal(wxID_CANCEL)          self.EndModal(wxID_CANCEL)
1234    
1235      def _OnSpin(self, event):      def _OnSpin(self, event):
# Line 1206  class SelectPropertiesDialog(wxDialog): Line 1238  class SelectPropertiesDialog(wxDialog):
1238    
1239      def __GetColor(self, cur):      def __GetColor(self, cur):
1240          dialog = wxColourDialog(self)          dialog = wxColourDialog(self)
1241          if cur is not Color.Transparent:          if cur is not Transparent:
1242              dialog.GetColourData().SetColour(Color2wxColour(cur))              dialog.GetColourData().SetColour(Color2wxColour(cur))
1243    
1244          ret = None          ret = None
# Line 1224  class SelectPropertiesDialog(wxDialog): Line 1256  class SelectPropertiesDialog(wxDialog):
1256          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer
1257    
1258      def _OnChangeLineColorTrans(self, event):      def _OnChangeLineColorTrans(self, event):
1259          self.prop.SetLineColor(Color.Transparent)          self.prop.SetLineColor(Transparent)
1260          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer
1261                    
1262      def _OnChangeFillColor(self, event):      def _OnChangeFillColor(self, event):
# Line 1234  class SelectPropertiesDialog(wxDialog): Line 1266  class SelectPropertiesDialog(wxDialog):
1266          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer
1267    
1268      def _OnChangeFillColorTrans(self, event):      def _OnChangeFillColorTrans(self, event):
1269          self.prop.SetFill(Color.Transparent)          self.prop.SetFill(Transparent)
1270          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer          self.previewWin.Refresh() # XXX: work around, see ClassDataPreviewer
1271    
1272      def GetClassGroupProperties(self):      def GetClassGroupProperties(self):
# Line 1290  class ClassDataPreviewer: Line 1322  class ClassDataPreviewer:
1322              h = rect.GetHeight()              h = rect.GetHeight()
1323    
1324          stroke = prop.GetLineColor()          stroke = prop.GetLineColor()
1325          if stroke is Color.Transparent:          if stroke is Transparent:
1326              pen = wxTRANSPARENT_PEN              pen = wxTRANSPARENT_PEN
1327          else:          else:
1328              pen = wxPen(Color2wxColour(stroke),              pen = wxPen(Color2wxColour(stroke),
# Line 1298  class ClassDataPreviewer: Line 1330  class ClassDataPreviewer:
1330                          wxSOLID)                          wxSOLID)
1331    
1332          stroke = prop.GetFill()          stroke = prop.GetFill()
1333          if stroke is Color.Transparent:          if stroke is Transparent:
1334              brush = wxTRANSPARENT_BRUSH              brush = wxTRANSPARENT_BRUSH
1335          else:          else:
1336              brush = wxBrush(Color2wxColour(stroke), wxSOLID)              brush = wxBrush(Color2wxColour(stroke), wxSOLID)
# Line 1357  class ClassGroupPropertiesCtrl(wxWindow, Line 1389  class ClassGroupPropertiesCtrl(wxWindow,
1389    
1390          wxWindow.__init__(self, parent, id, size = size, style = style)          wxWindow.__init__(self, parent, id, size = size, style = style)
1391    
1392            self.parent = parent
1393    
1394          self.SetProperties(props)          self.SetProperties(props)
1395          self.SetShapeType(shapeType)          self.SetShapeType(shapeType)
1396          self.AllowEdit(True)          self.AllowEdit(True)
# Line 1400  class ClassGroupPropertiesCtrl(wxWindow, Line 1434  class ClassGroupPropertiesCtrl(wxWindow,
1434      def DoEdit(self):      def DoEdit(self):
1435          if not self.allowEdit: return          if not self.allowEdit: return
1436    
1437          propDlg = SelectPropertiesDialog(NULL,          propDlg = SelectPropertiesDialog(self.parent,
1438                                           self.GetProperties(),                                           self.GetProperties(),
1439                                           self.GetShapeType())                                           self.GetShapeType())
1440    

Legend:
Removed from v.650  
changed lines
  Added in v.1464

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26