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

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

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

revision 14 by bh, Fri Aug 31 15:34:33 2001 UTC revision 177 by bh, Wed May 15 14:02:09 2002 UTC
# Line 1  Line 1 
1  #! /usr/bin/python  #! /usr/bin/python
2  # Copyright (c) 2001 by Intevation GmbH  # Copyright (c) 2001, 2002 by Intevation GmbH
3  # Authors:  # Authors:
4  # Jan-Oliver Wagner <[email protected]>  # Jan-Oliver Wagner <[email protected]>
5  # Bernhard Herzog <[email protected]>  # Bernhard Herzog <[email protected]>
# Line 15  from Thuban.Model.messages import MAPS_C Line 15  from Thuban.Model.messages import MAPS_C
15       LAYERS_CHANGED, LAYER_LEGEND_CHANGED, LAYER_VISIBILITY_CHANGED       LAYERS_CHANGED, LAYER_LEGEND_CHANGED, LAYER_VISIBILITY_CHANGED
16  from Thuban.Model.layer import Layer, shapetype_names  from Thuban.Model.layer import Layer, shapetype_names
17  from Thuban.Model.map import Map  from Thuban.Model.map import Map
 import view  
18    
19    from dialogs import NonModalDialog
20  from messages import SESSION_CHANGED, SELECTED_LAYER  from messages import SESSION_CHANGED, SELECTED_LAYER
21    
22  def color_string(color):  def color_string(color):
# Line 24  def color_string(color): Line 24  def color_string(color):
24          return "None"          return "None"
25      return "(%.3f, %.3f, %.3f)" % (color.red, color.green, color.blue)      return "(%.3f, %.3f, %.3f)" % (color.red, color.green, color.blue)
26    
 class myTreeCtrlPanel(wxPanel):  
27    
28      def __init__(self, parent, app):  class SessionTreeCtrl(wxTreeCtrl):
29    
30        # the session channels to subscribe to to update the tree
31        session_channels = (MAPS_CHANGED, MAP_PROJECTION_CHANGED,
32                            LAYERS_CHANGED, LAYER_LEGEND_CHANGED,
33                            LAYER_VISIBILITY_CHANGED)
34    
35        def __init__(self, parent, ID, app):
36          # Use the WANTS_CHARS style so the panel doesn't eat the Return key.          # Use the WANTS_CHARS style so the panel doesn't eat the Return key.
37          wxPanel.__init__(self, parent, -1, style=wxWANTS_CHARS)          wxTreeCtrl.__init__(self, parent, ID)
         self.app = app  
38    
39            self.app = app
40          # boolean to indicate that we manipulate the selection ourselves          # boolean to indicate that we manipulate the selection ourselves
41          # so that we can ignore the selection events generated          # so that we can ignore the selection events generated
42          self.changing_selection = 0          self.changing_selection = 0
43    
44          EVT_SIZE(self, self.OnSize)          # Dictionary mapping layer id's to tree items
45          self.tree = wxTreeCtrl(self, -1)          self.layer_to_item = {}
46    
47          self.app.Subscribe(SESSION_CHANGED, self.session_changed)          self.app.Subscribe(SESSION_CHANGED, self.session_changed)
48          self.app.interactor.Subscribe(SELECTED_LAYER, self.layer_selected)          self.app.interactor.Subscribe(SELECTED_LAYER, self.layer_selected)
49    
50            # the session currently displayed in the tree
51            self.session = None
52    
53          # pretend the session has changed to build the initial tree          # pretend the session has changed to build the initial tree
54          self.session_changed()          self.session_changed()
55    
56          EVT_TREE_SEL_CHANGED(self, self.tree.GetId(), self.OnSelChanged)          EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
57    
58        def unsubscribe_all(self):
59            if self.session is not None:
60                for channel in self.session_channels:
61                    self.session.Unsubscribe(channel, self.update_tree)
62                self.session = None
63            self.app.Unsubscribe(SESSION_CHANGED, self.session_changed)
64            self.app.interactor.Unsubscribe(SELECTED_LAYER, self.layer_selected)
65    
66      def update_tree(self, *args):      def update_tree(self, *args):
67          """Clear and rebuild the tree"""          """Clear and rebuild the tree"""
68          self.tree.DeleteAllItems()          self.DeleteAllItems()
69          session = self.app.session          session = self.app.session
70          root = self.tree.AddRoot("Session: %s" % session.title)          root = self.AddRoot("Session: %s" % session.title)
71            self.layer_to_item.clear()
72            if session.filename == None:
73                self.AppendItem(root, "Filename:")
74            else:
75                self.AppendItem(root, "Filename: %s" % session.filename)
76            if session.WasModified():
77                self.AppendItem(root, "Modified: yes")
78            else:
79                self.AppendItem(root, "Modified: no")
80    
81          for map in session.Maps():          for map in session.Maps():
82              mapitem = self.tree.AppendItem(root, "Map: %s" % map.title)              mapitem = self.AppendItem(root, "Map: %s" % map.title)
83              self.tree.SetPyData(mapitem, map)              self.SetPyData(mapitem, map)
84                if map.BoundingBox() != None:
85                    self.AppendItem(mapitem, ("Extent (lat-lon): (%g, %g, %g, %g)"
86                                              % map.BoundingBox()))
87              if map.projection and len(map.projection.params) > 0:              if map.projection and len(map.projection.params) > 0:
88                  projectionitem = self.tree.AppendItem(mapitem, "Projection")                  self.AppendItem(mapitem,
89                                    ("Extent (projected): (%g, %g, %g, %g)"
90                                     % map.ProjectedBoundingBox()))
91                    projectionitem = self.AppendItem(mapitem, "Projection")
92                  for param in map.projection.params:                  for param in map.projection.params:
93                      parameteritem = self.tree.AppendItem(projectionitem,                      parameteritem = self.AppendItem(projectionitem, str(param))
94                                                           str(param))                  self.Expand(projectionitem)
                 self.tree.Expand(projectionitem)  
95    
96              layers = map.Layers()              layers = map.Layers()
97              for layer_index in range(len(layers) - 1, -1, -1):              for layer_index in range(len(layers) - 1, -1, -1):
98                  layer = layers[layer_index]                  layer = layers[layer_index]
99                  idata = wxTreeItemData()                  idata = wxTreeItemData()
100                  idata.SetData(layer)                  idata.SetData(layer)
101                  layeritem = self.tree.AppendItem(mapitem,                  layeritem = self.AppendItem(mapitem,
102                                                   "Layer '%s'" % layer.Title(),                                              "Layer '%s'" % layer.Title(),
103                                                   data = idata)                                              data = idata)
104                    self.layer_to_item[id(layer)] = layeritem
105                  if layer is self.app.interactor.selected_layer:                  if layer is self.app.interactor.selected_layer:
106                      self.tree.SelectItem(layeritem)                      self.SelectItem(layeritem)
107                  if isinstance(layer, Layer):                  if isinstance(layer, Layer):
108                      if layer.Visible():                      if layer.Visible():
109                          text = "Shown"                          text = "Shown"
110                      else:                      else:
111                          text = "Hidden"                          text = "Hidden"
112                      self.tree.AppendItem(layeritem, text)                      self.AppendItem(layeritem, text)
113                      self.tree.AppendItem(layeritem,                      self.AppendItem(layeritem, "Shapes: %d" %layer.NumShapes())
114                                           "Shapes: %d" % layer.NumShapes())                      bbox = layer.LatLongBoundingBox()
115                      self.tree.AppendItem(layeritem,                      if bbox is not None:
116                                           ("Extents: (%g, %g, %g, %g)"                          self.AppendItem(layeritem,
117                                            % layer.LatLongBoundingBox()))                                          ("Extent (lat-lon): (%g, %g, %g, %g)"
118                      self.tree.AppendItem(layeritem,                                           % bbox))
119                                           "Shapetype: %s" %                      else:
120                                           shapetype_names[layer.ShapeType()])                          self.AppendItem(layeritem, ("Extent (lat-lon):"))
121                      self.tree.AppendItem(layeritem,                      self.AppendItem(layeritem,
122                                           "Fill: " + color_string(layer.fill))                                      "Shapetype: %s"
123                      self.tree.AppendItem(layeritem,                                      % shapetype_names[layer.ShapeType()])
124                                        "Outline: " + color_string(layer.stroke))                      self.AppendItem(layeritem,
125                  self.tree.Expand(layeritem)                                      "Fill: " + color_string(layer.fill))
126              self.tree.Expand(mapitem)                      self.AppendItem(layeritem,
127          self.tree.Expand(root)                                      "Outline: " + color_string(layer.stroke))
128                    self.Expand(layeritem)
129                self.Expand(mapitem)
130            self.Expand(root)
131    
132      def session_changed(self, *args):      def session_changed(self, *args):
133          for channel in (MAPS_CHANGED,          new_session = self.app.session
134                          MAP_PROJECTION_CHANGED,          # if the session has changed subscribe/unsubscribe
135                          LAYERS_CHANGED,          if self.session is not new_session:
136                          LAYER_LEGEND_CHANGED,              if self.session is not None:
137                          LAYER_VISIBILITY_CHANGED):                  for channel in self.session_channels:
138              self.app.session.Subscribe(channel, self.update_tree)                      self.session.Unsubscribe(channel, self.update_tree)
139                if new_session is not None:
140                    for channel in self.session_channels:
141                        new_session.Subscribe(channel, self.update_tree)
142                self.session = new_session
143          self.update_tree()          self.update_tree()
144    
     def OnSize(self, event):  
         w,h = self.GetClientSizeTuple()  
         self.tree.SetDimensions(0, 0, w, h)  
   
145      def normalize_selection(self):      def normalize_selection(self):
146          """Select the layer or map containing currently selected item"""          """Select the layer or map containing currently selected item"""
147          tree = self.tree          item = self.GetSelection()
         item = self.tree.GetSelection()  
148          while item.IsOk():          while item.IsOk():
149              object = tree.GetPyData(item)              object = self.GetPyData(item)
150              if isinstance(object, Layer) or isinstance(object, Map):              if isinstance(object, Layer) or isinstance(object, Map):
151                  break                  break
152              item = tree.GetItemParent(item)              item = self.GetItemParent(item)
153    
154          self.changing_selection = 1          self.changing_selection = 1
155          try:          try:
156              self.tree.SelectItem(item)              self.SelectItem(item)
157          finally:          finally:
158              self.changing_selection = 0              self.changing_selection = 0
159    
160      def SelectedLayer(self):      def SelectedLayer(self):
161          """Return the layer object currently selected in the tree.          """Return the layer object currently selected in the tree.
162          Return None if no layer is selected"""          Return None if no layer is selected"""
163          tree = self.tree          layer = self.GetPyData(self.GetSelection())
         layer = tree.GetPyData(tree.GetSelection())  
164          if isinstance(layer, Layer):          if isinstance(layer, Layer):
165              return layer              return layer
166          return None          return None
# Line 136  class myTreeCtrlPanel(wxPanel): Line 171  class myTreeCtrlPanel(wxPanel):
171              # self.normalize_selection(). ignore the event.              # self.normalize_selection(). ignore the event.
172              return              return
173          self.normalize_selection()          self.normalize_selection()
174          layer = self.SelectedLayer()          # SelectedLayer returns None if no layer is selected. Since
175          if layer is not None:          # passing None to interactor.SelectLayer deselects the layer we
176              self.app.interactor.SelectLayer(layer)          # can simply pass the result of SelectedLayer on in all cases
177            self.app.interactor.SelectLayer(self.SelectedLayer())
178    
179      def layer_selected(self, layer):      def layer_selected(self, layer):
180          pass          item = self.layer_to_item.get(id(layer))
181            if item is not None and item != self.GetSelection():
182                self.SelectItem(item)
183    
184    
185    class SessionTreeView(NonModalDialog):
186    
187        """Non modal dialog showing the session as a tree"""
188    
189        def __init__(self, parent, app, name):
190            NonModalDialog.__init__(self, parent, app.interactor, name, "Session")
191            self.tree = SessionTreeCtrl(self, -1, app)
192    
193        def OnClose(self, event):
194            #self.interactor.Unsubscribe(SELECTED_SHAPE, self.select_shape)
195            NonModalDialog.OnClose(self, event)
196    
197            # if there were a way to get notified when the tree control
198            # itself is destroyed we could use that to unsubscribe instead
199            # of doing it here. (EVT_WINDOW_DESTROY doesn't seem to sent at
200            # all)
201            self.tree.unsubscribe_all()

Legend:
Removed from v.14  
changed lines
  Added in v.177

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26