/[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 835 by bh, Tue May 6 15:52:41 2003 UTC revision 1058 by frank, Tue May 27 11:30:29 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.UI.common import *  from Thuban.UI.common import Color2wxColour, wxColour2Color
22    
23  from Thuban.Model.classification import *  from Thuban.Model.range import Range
24    from Thuban.Model.classification import \
25        Classification, ClassGroupDefault, \
26        ClassGroupSingleton, ClassGroupRange, ClassGroupMap, \
27        ClassGroupProperties
28    
29  from Thuban.Model.color import Color  from Thuban.Model.color import Color
30    
31  from Thuban.Model.layer import Layer, SHAPETYPE_ARC, SHAPETYPE_POLYGON, SHAPETYPE_POINT  from Thuban.Model.layer import Layer, RasterLayer, \
32        SHAPETYPE_ARC, SHAPETYPE_POLYGON, SHAPETYPE_POINT
33    
34  from Thuban.UI.classgen import ClassGenDialog, ClassGenerator  from Thuban.UI.classgen import ClassGenDialog, ClassGenerator
35    
36  from dialogs import NonModalDialog  from dialogs import NonModalNonParentDialog
37    
38  ID_CLASS_TABLE = 40011  ID_CLASS_TABLE = 40011
39    
# Line 243  class ClassGrid(wxGrid): Line 248  class ClassGrid(wxGrid):
248    
249      def _OnCellResize(self, event):      def _OnCellResize(self, event):
250          self.FitInside()          self.FitInside()
251            event.Skip()
252    
253  class ClassTable(wxPyGridTableBase):  class ClassTable(wxPyGridTableBase):
254      """Represents the underlying data structure for the grid."""      """Represents the underlying data structure for the grid."""
# Line 457  class ClassTable(wxPyGridTableBase): Line 463  class ClassTable(wxPyGridTableBase):
463          elif isinstance(group, ClassGroupSingleton):          elif isinstance(group, ClassGroupSingleton):
464              return group.GetValue()              return group.GetValue()
465          elif isinstance(group, ClassGroupRange):          elif isinstance(group, ClassGroupRange):
466              return _("%s - %s") % (group.GetMin(), group.GetMax())              return group.GetRange()
467    
468          assert(False) # shouldn't get here          assert False # shouldn't get here
469          return None          return None
470    
471      def __ParseInput(self, value):      def __ParseInput(self, value):
472          """Try to determine what kind of input value is          """Try to determine what kind of input value is
473             (string, number, or range)             (string, number, or range)
474    
475          Returns a tuple of length one if there is a single          Returns a tuple (type, data) where type is 0 if data is
476          value, or of length two if it is a range.          a singleton value, or 1 if is a range
477          """          """
478    
479          type = self.fieldType          type = self.fieldType
480    
481          if type == FIELDTYPE_STRING:          if type == FIELDTYPE_STRING:
482              return (value,)              return (0, value)
483          elif type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):          elif type in (FIELDTYPE_INT, FIELDTYPE_DOUBLE):
   
484              if type == FIELDTYPE_INT:              if type == FIELDTYPE_INT:
485                  # the float call allows the user to enter 1.0 for 1                  # the float call allows the user to enter 1.0 for 1
486                  conv = lambda p: int(float(p))                  conv = lambda p: int(float(p))
487              else:              else:
488                  conv = lambda p: p                  conv = float
489    
490              #              #
491              # first try to take the input as a single number              # first try to take the input as a single number
492              # if there's an exception try to break it into              # if there's an exception try to break it into
493              # a range seperated by a '-'. take care to ignore              # a range. if there is an exception here, let it
494              # 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.  
495              #              #
496              try:              try:
497                  return (conv(value),)                  return (0, conv(value))
498              except ValueError:              except ValueError:
499                  i = value.find('-')                  return (1, Range(value))
                 if i == 0:  
                     i = value.find('-', 1)  
   
                 return (conv(value[:i]), conv(value[i+1:]))  
500    
501          assert False  # shouldn't get here          assert False  # shouldn't get here
502          return (0,)          return (0,None)
               
503    
504      def SetValueAsCustom(self, row, col, typeName, value):      def SetValueAsCustom(self, row, col, typeName, value):
505          """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 553  class ClassTable(wxPyGridTableBase):
553                      # changing the underlying group type if the                      # changing the underlying group type if the
554                      # group was a singleton and a range was entered                      # group was a singleton and a range was entered
555                      #                      #
556                      if len(dataInfo) == 1:                      if dataInfo[0] == 0:
557                          if not isinstance(group, ClassGroupSingleton):                          if not isinstance(group, ClassGroupSingleton):
558                              ngroup = ClassGroupSingleton(props = props)                              ngroup = ClassGroupSingleton(props = props)
559                              changed = True                              changed = True
560                          ngroup.SetValue(dataInfo[0])                          ngroup.SetValue(dataInfo[1])
561                      elif len(dataInfo) == 2:                      elif dataInfo[0] == 1:
562                          if not isinstance(group, ClassGroupRange):                          if not isinstance(group, ClassGroupRange):
563                              ngroup = ClassGroupRange(props = props)                              ngroup = ClassGroupRange(props = props)
564                              changed = True                              changed = True
565                          ngroup.SetRange(dataInfo[0], dataInfo[1])                          ngroup.SetRange(dataInfo[1])
566                      else:                      else:
567                          assert False                          assert False
568                          pass                          pass
# Line 673  EB_LAYER_TITLE = 0 Line 670  EB_LAYER_TITLE = 0
670  EB_SELECT_FIELD = 1  EB_SELECT_FIELD = 1
671  EB_GEN_CLASS = 2  EB_GEN_CLASS = 2
672    
673  class Classifier(NonModalDialog):  class Classifier(NonModalNonParentDialog):
674    
675      type2string = {None:             _("None"),      type2string = {None:             _("None"),
676                     FIELDTYPE_STRING: _("Text"),                     FIELDTYPE_STRING: _("Text"),
# Line 681  class Classifier(NonModalDialog): Line 678  class Classifier(NonModalDialog):
678                     FIELDTYPE_DOUBLE: _("Decimal")}                     FIELDTYPE_DOUBLE: _("Decimal")}
679    
680      def __init__(self, parent, name, layer, group = None):      def __init__(self, parent, name, layer, group = None):
681          NonModalDialog.__init__(self, parent, name, "")          NonModalNonParentDialog.__init__(self, parent, name, "")
682    
683          self.__SetTitle(layer.Title())          self.__SetTitle(layer.Title())
684    
685          self.layer = layer          self.layer = layer
686    
         self.originalClass = self.layer.GetClassification()  
         field = self.originalClass.GetField()  
         fieldType = self.originalClass.GetFieldType()  
687    
688          self.genDlg = None          self.genDlg = None
689    
# Line 700  class Classifier(NonModalDialog): Line 694  class Classifier(NonModalDialog):
694          panel = wxPanel(self, -1)          panel = wxPanel(self, -1)
695    
696          text_title = wxTextCtrl(panel, ID_PROPERTY_TITLE, layer.Title())          text_title = wxTextCtrl(panel, ID_PROPERTY_TITLE, layer.Title())
697          #          self.fieldTypeText = wxStaticText(panel, -1, "")
         # make field choice box  
         #  
         self.fields = wxChoice(panel, ID_PROPERTY_SELECT,)  
   
         self.num_cols = layer.table.NumColumns()  
         # just assume the first field in case one hasn't been  
         # specified in the file.  
         self.__cur_field = 0  
698    
699          self.fields.Append("<None>")          if layer.HasClassification():
700                self.originalClass = self.layer.GetClassification()
701                field = self.originalClass.GetField()
702                fieldType = self.originalClass.GetFieldType()
703    
704          if self.originalClass.GetFieldType() is None:              #
705              self.fields.SetClientData(0, copy.deepcopy(self.originalClass))              # make field choice box
706          else:              #
707              self.fields.SetClientData(0, None)              self.fields = wxChoice(panel, ID_PROPERTY_SELECT,)
708    
709          for i in range(self.num_cols):              self.num_cols = layer.table.NumColumns()
710              name = layer.table.Column(i).name              # just assume the first field in case one hasn't been
711              self.fields.Append(name)              # specified in the file.
712                self.__cur_field = 0
             if name == field:  
                 self.__cur_field = i + 1  
                 self.fields.SetClientData(i + 1,  
                                           copy.deepcopy(self.originalClass))  
             else:  
                 self.fields.SetClientData(i + 1, None)  
713    
714                self.fields.Append("<None>")
715    
716          self.fieldTypeText = wxStaticText(panel, -1, "")              if self.originalClass.GetFieldType() is None:
717                    self.fields.SetClientData(0, copy.deepcopy(self.originalClass))
718          button_gen = wxButton(panel, ID_PROPERTY_GENCLASS, _("Generate Class"))              else:
719                    self.fields.SetClientData(0, None)
720    
721          button_add = wxButton(panel, ID_PROPERTY_ADD, _("Add"))              for i in range(self.num_cols):
722          button_moveup = wxButton(panel, ID_PROPERTY_MOVEUP, _("Move Up"))                  name = layer.table.Column(i).name
723          button_movedown = wxButton(panel, ID_PROPERTY_MOVEDOWN, _("Move Down"))                  self.fields.Append(name)
724          button_edit = wxButton(panel, ID_PROPERTY_EDITSYM, _("Edit Symbol"))  
725          button_remove = wxButton(panel, ID_PROPERTY_REMOVE, _("Remove"))                  if name == field:
726                        self.__cur_field = i + 1
727                        self.fields.SetClientData(i + 1,
728                                                copy.deepcopy(self.originalClass))
729                    else:
730                        self.fields.SetClientData(i + 1, None)
731    
732                button_gen = wxButton(panel, ID_PROPERTY_GENCLASS,
733                    _("Generate Class"))
734                button_add = wxButton(panel, ID_PROPERTY_ADD,
735                    _("Add"))
736                button_moveup = wxButton(panel, ID_PROPERTY_MOVEUP,
737                    _("Move Up"))
738                button_movedown = wxButton(panel, ID_PROPERTY_MOVEDOWN,
739                    _("Move Down"))
740                button_edit = wxButton(panel, ID_PROPERTY_EDITSYM,
741                    _("Edit Symbol"))
742                button_remove = wxButton(panel, ID_PROPERTY_REMOVE,
743                    _("Remove"))
744    
745                self.classGrid = ClassGrid(panel, self)
746    
747                # calling __SelectField after creating the classGrid fills in the
748                # grid with the correct information
749                self.fields.SetSelection(self.__cur_field)
750                self.__SelectField(self.__cur_field, group = group)
751    
752          button_try = wxButton(panel, ID_PROPERTY_TRY, _("Try"))          button_try = wxButton(self, ID_PROPERTY_TRY, _("Try"))
753          button_revert = wxButton(panel, ID_PROPERTY_REVERT, _("Revert"))          button_revert = wxButton(self, ID_PROPERTY_REVERT, _("Revert"))
754          button_ok = wxButton(panel, wxID_OK, _("OK"))          button_ok = wxButton(self, wxID_OK, _("OK"))
755          button_ok.SetDefault()          button_ok.SetDefault()
756          button_close = wxButton(panel, wxID_CANCEL, _("Close"))          button_close = wxButton(self, wxID_CANCEL, _("Close"))
   
         self.classGrid = ClassGrid(panel, self)  
   
         # calling __SelectField after creating the classGrid fills in the  
         # grid with the correct information  
         self.fields.SetSelection(self.__cur_field)  
         self.__SelectField(self.__cur_field, group = group)  
757    
758          ############################          ############################
759          # Layout the controls          # Layout the controls
# Line 767  class Classifier(NonModalDialog): Line 769  class Classifier(NonModalDialog):
769    
770          panelBox.Add(sizer, 0, wxGROW, 4)          panelBox.Add(sizer, 0, wxGROW, 4)
771    
772          panelBox.Add(wxStaticText(panel, -1,          if isinstance(layer, RasterLayer):
773                                  _("Type: %s") % layer.ShapeType()),              type = "Image"
774            else:
775                type = layer.ShapeType()
776    
777            panelBox.Add(wxStaticText(panel, -1, _("Type: %s") % type),
778              0, wxALIGN_LEFT | wxALL, 4)              0, wxALIGN_LEFT | wxALL, 4)
779    
780          classBox = wxStaticBoxSizer(          if layer.HasClassification():
                     wxStaticBox(panel, -1, _("Classification")), wxVERTICAL)  
781    
782                classBox = wxStaticBoxSizer(
783                            wxStaticBox(panel, -1, _("Classification")), wxVERTICAL)
784    
         sizer = wxBoxSizer(wxHORIZONTAL)  
         sizer.Add(wxStaticText(panel, ID_PROPERTY_FIELDTEXT, _("Field: ")),  
             0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 4)  
         sizer.Add(self.fields, 1, wxGROW | wxALL, 4)  
   
         classBox.Add(sizer, 0, wxGROW, 4)  
   
         classBox.Add(self.fieldTypeText, 0,  
                      wxGROW | wxALIGN_LEFT | wxALL | wxADJUST_MINSIZE, 4)  
   
         controlBox = wxBoxSizer(wxHORIZONTAL)  
         controlButtonBox = wxBoxSizer(wxVERTICAL)  
   
         controlButtonBox.Add(button_gen, 0, wxGROW|wxALL, 4)  
         controlButtonBox.Add(button_add, 0, wxGROW|wxALL, 4)  
         controlButtonBox.Add(button_moveup, 0, wxGROW|wxALL, 4)  
         controlButtonBox.Add(button_movedown, 0, wxGROW|wxALL, 4)  
         controlButtonBox.Add(button_edit, 0, wxGROW|wxALL, 4)  
         controlButtonBox.Add(60, 20, 0, wxGROW|wxALL|wxALIGN_BOTTOM, 4)  
         controlButtonBox.Add(button_remove, 0, wxGROW|wxALL|wxALIGN_BOTTOM, 4)  
785    
786          controlBox.Add(self.classGrid, 1, wxGROW, 0)              sizer = wxBoxSizer(wxHORIZONTAL)
787          controlBox.Add(controlButtonBox, 0, wxGROW, 10)              sizer.Add(wxStaticText(panel, ID_PROPERTY_FIELDTEXT, _("Field: ")),
788                    0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 4)
789                sizer.Add(self.fields, 1, wxGROW | wxALL, 4)
790    
791                classBox.Add(sizer, 0, wxGROW, 4)
792    
793                classBox.Add(self.fieldTypeText, 0,
794                            wxGROW | wxALIGN_LEFT | wxALL | wxADJUST_MINSIZE, 4)
795    
796          classBox.Add(controlBox, 1, wxGROW, 10)              controlBox = wxBoxSizer(wxHORIZONTAL)
797          panelBox.Add(classBox, 1, wxGROW, 0)              controlButtonBox = wxBoxSizer(wxVERTICAL)
798    
799                controlButtonBox.Add(button_gen, 0, wxGROW|wxALL, 4)
800                controlButtonBox.Add(button_add, 0, wxGROW|wxALL, 4)
801                controlButtonBox.Add(button_moveup, 0, wxGROW|wxALL, 4)
802                controlButtonBox.Add(button_movedown, 0, wxGROW|wxALL, 4)
803                controlButtonBox.Add(button_edit, 0, wxGROW|wxALL, 4)
804                controlButtonBox.Add(60, 20, 0, wxGROW|wxALL|wxALIGN_BOTTOM, 4)
805                controlButtonBox.Add(button_remove, 0,
806                                     wxGROW|wxALL|wxALIGN_BOTTOM, 4)
807    
808                controlBox.Add(self.classGrid, 1, wxGROW, 0)
809                controlBox.Add(controlButtonBox, 0, wxGROW, 10)
810    
811                classBox.Add(controlBox, 1, wxGROW, 10)
812                panelBox.Add(classBox, 1, wxGROW, 0)
813    
814    
815          buttonBox = wxBoxSizer(wxHORIZONTAL)          buttonBox = wxBoxSizer(wxHORIZONTAL)
816          buttonBox.Add(button_try, 0, wxALL, 4)          buttonBox.Add(button_try, 0, wxRIGHT|wxEXPAND, 10)
817          buttonBox.Add(60, 20, 0, wxALL, 4)          buttonBox.Add(button_revert, 0, wxRIGHT|wxEXPAND, 10)
818          buttonBox.Add(button_revert, 0, wxALL, 4)          buttonBox.Add(button_ok, 0, wxRIGHT|wxEXPAND, 10)
819          buttonBox.Add(60, 20, 0, wxALL, 4)          buttonBox.Add(button_close, 0, wxRIGHT|wxEXPAND, 10)
         buttonBox.Add(button_ok, 0, wxALL, 4)  
         buttonBox.Add(60, 20, 0, wxALL, 4)  
         buttonBox.Add(button_close, 0, wxALL, 4)  
         panelBox.Add(buttonBox, 0,  
             wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 0)  
820    
821          panel.SetAutoLayout(True)          panel.SetAutoLayout(True)
822          panel.SetSizer(panelBox)          panel.SetSizer(panelBox)
# Line 820  class Classifier(NonModalDialog): Line 824  class Classifier(NonModalDialog):
824          panelBox.SetSizeHints(panel)          panelBox.SetSizeHints(panel)
825    
826          topBox.Add(panel, 1, wxGROW | wxALL, 4)          topBox.Add(panel, 1, wxGROW | wxALL, 4)
827            topBox.Add(buttonBox, 0, wxALIGN_RIGHT|wxBOTTOM|wxTOP, 10)
828    
829          self.SetAutoLayout(True)          self.SetAutoLayout(True)
830          self.SetSizer(topBox)          self.SetSizer(topBox)
# Line 845  class Classifier(NonModalDialog): Line 850  class Classifier(NonModalDialog):
850    
851          ######################          ######################
852    
853          self.fields.SetFocus()          text_title.SetFocus()
854          self.haveApplied = False          self.haveApplied = False
855    
856      def EditSymbol(self, row):      def EditSymbol(self, row):
# Line 964  class Classifier(NonModalDialog): Line 969  class Classifier(NonModalDialog):
969             it to the layer.             it to the layer.
970          """          """
971    
972          clazz = self.fields.GetClientData(self.__cur_field)          if self.layer.HasClassification():
973                clazz = self.fields.GetClientData(self.__cur_field)
974    
975          #              #
976          # only build the classification if there wasn't one to              # only build the classification if there wasn't one to
977          # to begin with or it has been modified              # to begin with or it has been modified
978          #              #
979          if clazz is None or self.classGrid.GetTable().IsModified():              self.classGrid.SaveEditControlValue()
980              clazz = self.__BuildClassification(self.__cur_field, True)              if clazz is None or self.classGrid.GetTable().IsModified():
981                    clazz = self.__BuildClassification(self.__cur_field, True)
982    
983          self.layer.SetClassification(clazz)              self.layer.SetClassification(clazz)
984    
985          self.haveApplied = True          self.haveApplied = True
986    
# Line 982  class Classifier(NonModalDialog): Line 989  class Classifier(NonModalDialog):
989          self.Close()          self.Close()
990    
991      def OnClose(self, event):      def OnClose(self, event):
992          NonModalDialog.OnClose(self, event)          NonModalNonParentDialog.OnClose(self, event)
993    
994      def _OnCloseBtn(self, event):      def _OnCloseBtn(self, event):
995          """Close is similar to Cancel except that any changes that were          """Close is similar to Cancel except that any changes that were
# Line 1169  class SelectPropertiesDialog(wxDialog): Line 1176  class SelectPropertiesDialog(wxDialog):
1176          buttonBox = wxBoxSizer(wxHORIZONTAL)          buttonBox = wxBoxSizer(wxHORIZONTAL)
1177          button_ok = wxButton(self, wxID_OK, _("OK"))          button_ok = wxButton(self, wxID_OK, _("OK"))
1178          button_ok.SetDefault()          button_ok.SetDefault()
1179          buttonBox.Add(button_ok, 0, wxALL, 4)          buttonBox.Add(button_ok, 0, wxRIGHT|wxEXPAND, 10)
1180          buttonBox.Add(wxButton(self, wxID_CANCEL, _("Cancel")),          buttonBox.Add(wxButton(self, wxID_CANCEL, _("Cancel")),
1181                        0, wxALL, 4)                        0, wxRIGHT|wxEXPAND, 10)
1182          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)          topBox.Add(buttonBox, 0, wxALIGN_RIGHT|wxBOTTOM|wxTOP, 10)
1183                                                                                                                                                                    
1184          #EVT_BUTTON(self, wxID_OK, self._OnOK)          #EVT_BUTTON(self, wxID_OK, self._OnOK)
1185          #EVT_BUTTON(self, ID_SELPROP_CANCEL, self._OnCancel)          #EVT_BUTTON(self, ID_SELPROP_CANCEL, self._OnCancel)

Legend:
Removed from v.835  
changed lines
  Added in v.1058

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26