/[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 1452 by bh, Fri Jul 18 12:57:59 2003 UTC revision 2366 by joey, Fri Oct 1 18:24:10 2004 UTC
# Line 29  from Thuban.Model.classification import Line 29  from Thuban.Model.classification import
29    
30  from Thuban.Model.color import Transparent  from Thuban.Model.color import Transparent
31    
32  from Thuban.Model.layer import Layer, RasterLayer, \  from Thuban.Model.layer import Layer, RasterLayer
33      SHAPETYPE_ARC, SHAPETYPE_POLYGON, SHAPETYPE_POINT  from Thuban.Model.data import SHAPETYPE_ARC, SHAPETYPE_POLYGON, SHAPETYPE_POINT
34    
35  from Thuban.UI.classgen import ClassGenDialog  from Thuban.UI.classgen import ClassGenDialog
36    from Thuban.UI.colordialog import ColorDialog
37    
38  from dialogs import NonModalNonParentDialog  from dialogs import NonModalNonParentDialog
39    from messages import MAP_REPLACED
40    
41  ID_CLASS_TABLE = 40011  ID_CLASS_TABLE = 40011
42    
# Line 315  class ClassTable(wxPyGridTableBase): Line 317  class ClassTable(wxPyGridTableBase):
317          self.GetView().FitInside()          self.GetView().FitInside()
318    
319      def GetClassification(self):      def GetClassification(self):
320            """Return the current classification."""
321          return self.clazz          return self.clazz
322    
323      def SetClassification(self, clazz, group = None):      def SetClassification(self, clazz, group = None):
324            """Fill in the table with the given classification.
325            Select the given group if group is not None.
326            """
327    
328          self.GetView().BeginBatch()          self.GetView().BeginBatch()
329    
# Line 338  class ClassTable(wxPyGridTableBase): Line 344  class ClassTable(wxPyGridTableBase):
344    
345          self.__Modified()          self.__Modified()
346    
   
347          self.GetView().EndBatch()          self.GetView().EndBatch()
348          self.GetView().FitInside()          self.GetView().FitInside()
349    
350      def __NotifyRowChanges(self, curRows, newRows):      def __NotifyRowChanges(self, curRows, newRows):
351            """Make sure table updates correctly if the number of
352            rows changes.
353            """
354          #          #
355          # silly message processing for updates to the number of          # silly message processing for updates to the number of
356          # rows and columns          # rows and columns
# Line 361  class ClassTable(wxPyGridTableBase): Line 369  class ClassTable(wxPyGridTableBase):
369              self.GetView().ProcessTableMessage(msg)              self.GetView().ProcessTableMessage(msg)
370              self.GetView().FitInside()              self.GetView().FitInside()
371    
   
372      def __SetRow(self, row, group):      def __SetRow(self, row, group):
373          """Set a row's data to that of the group.          """Set a row's data to that of the group.
374    
# Line 593  class ClassTable(wxPyGridTableBase): Line 600  class ClassTable(wxPyGridTableBase):
600              return self.clazz.GetGroup(row - 1)              return self.clazz.GetGroup(row - 1)
601    
602      def SetClassGroup(self, row, group):      def SetClassGroup(self, row, group):
603            """Set the given row to properties of group."""
604          self.__SetRow(row, group)          self.__SetRow(row, group)
605          self.GetView().Refresh()          self.GetView().Refresh()
606    
# Line 677  class Classifier(NonModalNonParentDialog Line 685  class Classifier(NonModalNonParentDialog
685                     FIELDTYPE_INT:    _("Integer"),                     FIELDTYPE_INT:    _("Integer"),
686                     FIELDTYPE_DOUBLE: _("Decimal")}                     FIELDTYPE_DOUBLE: _("Decimal")}
687    
688      def __init__(self, parent, name, map, layer, group = None):      def __init__(self, parent, name, layer, group = None):
689            """Create a Properties/Classification dialog for a layer.
690            The layer is part of map. If group is not None, select that
691            group in the classification table.
692            """
693    
694          NonModalNonParentDialog.__init__(self, parent, name, "")          NonModalNonParentDialog.__init__(self, parent, name, "")
695    
696          self.__SetTitle(layer.Title())          self.__SetTitle(layer.Title())
697    
698            self.parent.Subscribe(MAP_REPLACED, self.map_replaced)
699          self.layer = layer          self.layer = layer
700          self.map = map          self.map = parent.Map()
701    
702          self.map.Subscribe(MAP_LAYERS_REMOVED, self.map_layers_removed)          self.map.Subscribe(MAP_LAYERS_REMOVED, self.map_layers_removed)
703          self.layer.Subscribe(LAYER_SHAPESTORE_REPLACED,          self.layer.Subscribe(LAYER_SHAPESTORE_REPLACED,
# Line 860  class Classifier(NonModalNonParentDialog Line 874  class Classifier(NonModalNonParentDialog
874          self.haveApplied = False          self.haveApplied = False
875    
876      def unsubscribe_messages(self):      def unsubscribe_messages(self):
877            """Unsubscribe from all messages."""
878            self.parent.Unsubscribe(MAP_REPLACED, self.map_replaced)
879          self.map.Unsubscribe(MAP_LAYERS_REMOVED, self.map_layers_removed)          self.map.Unsubscribe(MAP_LAYERS_REMOVED, self.map_layers_removed)
880          self.layer.Unsubscribe(LAYER_SHAPESTORE_REPLACED,          self.layer.Unsubscribe(LAYER_SHAPESTORE_REPLACED,
881                                 self.layer_shapestore_replaced)                                 self.layer_shapestore_replaced)
882    
883      def map_layers_removed(self, map):      def map_layers_removed(self, map):
884            """Subscribed to MAP_LAYERS_REMOVED. If this layer was removed,
885            Close self.
886            """
887          if self.layer not in self.map.Layers():          if self.layer not in self.map.Layers():
888              self.Close()              self.Close()
889    
890      def layer_shapestore_replaced(self, *args):      def layer_shapestore_replaced(self, *args):
891            """Subscribed to the map's LAYER_SHAPESTORE_REPLACED message.
892    
893            Close self.
894            """
895            self.Close()
896    
897        def map_replaced(self, *args):
898            """Subscribed to the mainwindow's MAP_REPLACED message. Close self."""
899          self.Close()          self.Close()
900    
901      def EditSymbol(self, row):      def EditSymbol(self, row):
902            """Open up a dialog where the user can select the properties
903            for a group.
904            """
905          table = self.classGrid.GetTable()          table = self.classGrid.GetTable()
906          prop = table.GetValueAsCustom(row, COL_SYMBOL, None)          prop = table.GetValueAsCustom(row, COL_SYMBOL, None)
907    
# Line 887  class Classifier(NonModalNonParentDialog Line 917  class Classifier(NonModalNonParentDialog
917          propDlg.Destroy()          propDlg.Destroy()
918                    
919      def _SetClassification(self, clazz):      def _SetClassification(self, clazz):
920            """Called from the ClassGen dialog when a new classification has
921            been created and should be set in the table.
922            """
923            # FIXME: This could be implemented using a message
924                    
925          self.fields.SetClientData(self.__cur_field, clazz)          self.fields.SetClientData(self.__cur_field, clazz)
926          self.classGrid.GetTable().SetClassification(clazz)          self.classGrid.GetTable().SetClassification(clazz)
927    
928      def __BuildClassification(self, fieldIndex, copyClass=False, force=False):      def __BuildClassification(self, fieldIndex, copyClass=False, force=False):
929            """Pack the classification setting into a Classification object.
930            Returns (Classification, fieldName) where fieldName is the selected
931            field in the table that the classification should be used with.
932            """
933    
934  #       numRows = self.classGrid.GetNumberRows()  #       numRows = self.classGrid.GetNumberRows()
935  #       assert numRows > 0  # there should always be a default row  #       assert numRows > 0  # there should always be a default row
# Line 912  class Classifier(NonModalNonParentDialog Line 950  class Classifier(NonModalNonParentDialog
950          return clazz, fieldName          return clazz, fieldName
951    
952      def __SetGridTable(self, fieldIndex, group = None):      def __SetGridTable(self, fieldIndex, group = None):
953            """Set the table with the classification associated with the
954            selected field at fieldIndex. Select the specified group
955            if group is not None.
956            """
957    
958          clazz = self.fields.GetClientData(fieldIndex)          clazz = self.fields.GetClientData(fieldIndex)
959    
# Line 929  class Classifier(NonModalNonParentDialog Line 971  class Classifier(NonModalNonParentDialog
971                                     self.layer.ShapeType(), group)                                     self.layer.ShapeType(), group)
972    
973      def __SetFieldTypeText(self, fieldIndex):      def __SetFieldTypeText(self, fieldIndex):
974            """Set the field type string using the data type of the field
975            at fieldIndex.
976            """
977          fieldName = self.fields.GetString(fieldIndex)          fieldName = self.fields.GetString(fieldIndex)
978          fieldType = self.layer.GetFieldType(fieldName)          fieldType = self.layer.GetFieldType(fieldName)
979    
# Line 956  class Classifier(NonModalNonParentDialog Line 1001  class Classifier(NonModalNonParentDialog
1001          self.__SetFieldTypeText(newIndex)          self.__SetFieldTypeText(newIndex)
1002    
1003      def __SetTitle(self, title):      def __SetTitle(self, title):
1004            """Set the title of the dialog."""
1005          if title != "":          if title != "":
1006              title = ": " + title              title = ": " + title
1007    
1008          self.SetTitle(_("Layer Properties") + title)          self.SetTitle(_("Layer Properties") + title)
1009    
1010      def _OnEditSymbol(self, event):      def _OnEditSymbol(self, event):
1011            """Open up a dialog for the user to select group properties."""
1012          sel = self.classGrid.GetCurrentSelection()          sel = self.classGrid.GetCurrentSelection()
1013    
1014          if len(sel) == 1:          if len(sel) == 1:
# Line 1023  class Classifier(NonModalNonParentDialog Line 1070  class Classifier(NonModalNonParentDialog
1070          self.classGrid.DeleteSelectedRows()          self.classGrid.DeleteSelectedRows()
1071    
1072      def _OnGenClass(self, event):      def _OnGenClass(self, event):
1073            """Open up a dialog for the user to generate classifications."""
1074    
1075          self.genDlg = ClassGenDialog(self, self.layer,          self.genDlg = ClassGenDialog(self, self.layer,
1076                            self.fields.GetString(self.__cur_field))                            self.fields.GetString(self.__cur_field))
# Line 1034  class Classifier(NonModalNonParentDialog Line 1082  class Classifier(NonModalNonParentDialog
1082          self.genDlg.Show()          self.genDlg.Show()
1083    
1084      def _OnGenDialogClose(self, event):      def _OnGenDialogClose(self, event):
1085            """Reenable buttons after the generate classification
1086            dialog is closed.
1087            """
1088          self.genDlg.Destroy()          self.genDlg.Destroy()
1089          self.genDlg = None          self.genDlg = None
1090          self.__EnableButtons(EB_GEN_CLASS)          self.__EnableButtons(EB_GEN_CLASS)
1091    
1092      def _OnMoveUp(self, event):      def _OnMoveUp(self, event):
1093            """When the user clicks MoveUp, try to move a group up one row."""
1094          sel = self.classGrid.GetCurrentSelection()          sel = self.classGrid.GetCurrentSelection()
1095    
1096          if len(sel) == 1:          if len(sel) == 1:
# Line 1054  class Classifier(NonModalNonParentDialog Line 1106  class Classifier(NonModalNonParentDialog
1106                  self.classGrid.MakeCellVisible(i - 1, 0)                  self.classGrid.MakeCellVisible(i - 1, 0)
1107    
1108      def _OnMoveDown(self, event):      def _OnMoveDown(self, event):
1109            """When the user clicks MoveDown, try to move a group down one row."""
1110          sel = self.classGrid.GetCurrentSelection()          sel = self.classGrid.GetCurrentSelection()
1111    
1112          if len(sel) == 1:          if len(sel) == 1:
# Line 1069  class Classifier(NonModalNonParentDialog Line 1122  class Classifier(NonModalNonParentDialog
1122                  self.classGrid.MakeCellVisible(i + 1, 0)                  self.classGrid.MakeCellVisible(i + 1, 0)
1123    
1124      def _OnTitleChanged(self, event):      def _OnTitleChanged(self, event):
1125            """Update the dialog title when the user changed the layer name."""
1126          obj = event.GetEventObject()          obj = event.GetEventObject()
1127    
1128          self.layer.SetTitle(obj.GetValue())          self.layer.SetTitle(obj.GetValue())
# Line 1077  class Classifier(NonModalNonParentDialog Line 1131  class Classifier(NonModalNonParentDialog
1131          self.__EnableButtons(EB_LAYER_TITLE)          self.__EnableButtons(EB_LAYER_TITLE)
1132    
1133      def __EnableButtons(self, case):      def __EnableButtons(self, case):
1134            """Helper method that enables/disables the appropriate buttons
1135            based on the case provided. Cases are constants beginning with EB_.
1136            """
1137    
1138          list = {wxID_OK                 : True,          list = {wxID_OK                 : True,
1139                  wxID_CANCEL             : True,                  wxID_CANCEL             : True,
# Line 1121  ID_SELPROP_STROKECLRTRANS = 4006 Line 1178  ID_SELPROP_STROKECLRTRANS = 4006
1178  ID_SELPROP_FILLCLRTRANS = 4007  ID_SELPROP_FILLCLRTRANS = 4007
1179    
1180  class SelectPropertiesDialog(wxDialog):  class SelectPropertiesDialog(wxDialog):
1181        """Dialog that allows the user to select group properties."""
1182    
1183      def __init__(self, parent, prop, shapeType):      def __init__(self, parent, prop, shapeType):
1184            """Open the dialog with the initial prop properties and shapeType."""
1185    
1186          wxDialog.__init__(self, parent, -1, _("Select Properties"),          wxDialog.__init__(self, parent, -1, _("Select Properties"),
1187                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)                            style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
1188    
# Line 1226  class SelectPropertiesDialog(wxDialog): Line 1286  class SelectPropertiesDialog(wxDialog):
1286          self.previewWin.Refresh()          self.previewWin.Refresh()
1287    
1288      def __GetColor(self, cur):      def __GetColor(self, cur):
1289          dialog = wxColourDialog(self)          dialog = ColorDialog(self)
1290          if cur is not Transparent:          dialog.SetColor(cur)
             dialog.GetColourData().SetColour(Color2wxColour(cur))  
1291    
1292          ret = None          ret = None
1293          if dialog.ShowModal() == wxID_OK:          if dialog.ShowModal() == wxID_OK:
1294              ret = wxColour2Color(dialog.GetColourData().GetColour())              ret = dialog.GetColor()
1295    
1296          dialog.Destroy()          dialog.Destroy()
1297    
# Line 1263  class SelectPropertiesDialog(wxDialog): Line 1322  class SelectPropertiesDialog(wxDialog):
1322    
1323    
1324  class ClassDataPreviewWindow(wxWindow):  class ClassDataPreviewWindow(wxWindow):
1325        """A custom window that draws group properties using the correct shape."""
1326    
1327      def __init__(self, rect, prop, shapeType,      def __init__(self, rect, prop, shapeType,
1328                         parent = None, id = -1, size = wxDefaultSize):                         parent = None, id = -1, size = wxDefaultSize):
1329            """Draws the appropriate shape as specified with shapeType using
1330            prop properities.
1331            """
1332          if parent is not None:          if parent is not None:
1333              wxWindow.__init__(self, parent, id, (0, 0), size)              wxWindow.__init__(self, parent, id, (0, 0), size)
1334              EVT_PAINT(self, self._OnPaint)              EVT_PAINT(self, self._OnPaint)
# Line 1294  class ClassDataPreviewWindow(wxWindow): Line 1357  class ClassDataPreviewWindow(wxWindow):
1357          self.previewer.Draw(dc, rect, self.prop, self.shapeType)          self.previewer.Draw(dc, rect, self.prop, self.shapeType)
1358    
1359  class ClassDataPreviewer:  class ClassDataPreviewer:
1360        """Class that actually draws a group property preview."""
1361    
1362      def Draw(self, dc, rect, prop, shapeType):      def Draw(self, dc, rect, prop, shapeType):
1363    
# Line 1342  class ClassDataPreviewer: Line 1406  class ClassDataPreviewer:
1406              dc.DrawRectangle(x, y, w, h)              dc.DrawRectangle(x, y, w, h)
1407    
1408  class ClassRenderer(wxPyGridCellRenderer):  class ClassRenderer(wxPyGridCellRenderer):
1409        """A wrapper class that can be used to draw group properties in a
1410        grid table.
1411        """
1412    
1413      def __init__(self, shapeType):      def __init__(self, shapeType):
1414          wxPyGridCellRenderer.__init__(self)          wxPyGridCellRenderer.__init__(self)
# Line 1372  class ClassRenderer(wxPyGridCellRenderer Line 1439  class ClassRenderer(wxPyGridCellRenderer
1439    
1440    
1441  class ClassGroupPropertiesCtrl(wxWindow, wxControl):  class ClassGroupPropertiesCtrl(wxWindow, wxControl):
1442        """A custom window and control that draw a preview of group properties
1443        and can open a dialog to modify the properties if the user double-clicks
1444        it.
1445        """
1446    
1447      def __init__(self, parent, id, props, shapeType,      def __init__(self, parent, id, props, shapeType,
1448                   size = wxDefaultSize, style = 0):                   size = wxDefaultSize, style = 0):
# Line 1418  class ClassGroupPropertiesCtrl(wxWindow, Line 1489  class ClassGroupPropertiesCtrl(wxWindow,
1489          self.Refresh()          self.Refresh()
1490    
1491      def AllowEdit(self, allow):      def AllowEdit(self, allow):
1492            """Allow/Disallow double-clicking on the control."""
1493          self.allowEdit = allow          self.allowEdit = allow
1494    
1495      def DoEdit(self):      def DoEdit(self):
1496            """Open the properties selector dialog."""
1497    
1498          if not self.allowEdit: return          if not self.allowEdit: return
1499    
1500          propDlg = SelectPropertiesDialog(self.parent,          propDlg = SelectPropertiesDialog(self.parent,
# Line 1436  class ClassGroupPropertiesCtrl(wxWindow, Line 1510  class ClassGroupPropertiesCtrl(wxWindow,
1510    
1511      def _OnLeftDClick(self, event):      def _OnLeftDClick(self, event):
1512          self.DoEdit()          self.DoEdit()
1513    
1514    from Thuban.UI.mainwindow import layer_properties_dialogs
1515    layer_properties_dialogs.add(Layer, Classifier)
1516    layer_properties_dialogs.add(RasterLayer, Classifier)

Legend:
Removed from v.1452  
changed lines
  Added in v.2366

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26