/[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 151 by bh, Tue May 7 17:01:35 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            print "unsubscribe_all"
60            if self.session is not None:
61                for channel in self.session_channels:
62                    self.session.Unsubscribe(channel, self.update_tree)
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())                      self.AppendItem(layeritem,
115                      self.tree.AppendItem(layeritem,                                      ("Extent (lat-lon): (%g, %g, %g, %g)"
116                                           ("Extents: (%g, %g, %g, %g)"                                       % layer.LatLongBoundingBox()))
117                                            % layer.LatLongBoundingBox()))                      self.AppendItem(layeritem,
118                      self.tree.AppendItem(layeritem,                                      "Shapetype: %s"
119                                           "Shapetype: %s" %                                      % shapetype_names[layer.ShapeType()])
120                                           shapetype_names[layer.ShapeType()])                      self.AppendItem(layeritem,
121                      self.tree.AppendItem(layeritem,                                      "Fill: " + color_string(layer.fill))
122                                           "Fill: " + color_string(layer.fill))                      self.AppendItem(layeritem,
123                      self.tree.AppendItem(layeritem,                                      "Outline: " + color_string(layer.stroke))
124                                        "Outline: " + color_string(layer.stroke))                  self.Expand(layeritem)
125                  self.tree.Expand(layeritem)              self.Expand(mapitem)
126              self.tree.Expand(mapitem)          self.Expand(root)
         self.tree.Expand(root)  
127    
128      def session_changed(self, *args):      def session_changed(self, *args):
129          for channel in (MAPS_CHANGED,          new_session = self.app.session
130                          MAP_PROJECTION_CHANGED,          # if the session has changed subscribe/unsubscribe
131                          LAYERS_CHANGED,          if self.session is not new_session:
132                          LAYER_LEGEND_CHANGED,              if self.session is not None:
133                          LAYER_VISIBILITY_CHANGED):                  for channel in self.session_channels:
134              self.app.session.Subscribe(channel, self.update_tree)                      self.session.Unsubscribe(channel, self.update_tree)
135                if new_session is not None:
136                    for channel in self.session_channels:
137                        new_session.Subscribe(channel, self.update_tree)
138                self.session = new_session
139          self.update_tree()          self.update_tree()
140    
     def OnSize(self, event):  
         w,h = self.GetClientSizeTuple()  
         self.tree.SetDimensions(0, 0, w, h)  
   
141      def normalize_selection(self):      def normalize_selection(self):
142          """Select the layer or map containing currently selected item"""          """Select the layer or map containing currently selected item"""
143          tree = self.tree          item = self.GetSelection()
         item = self.tree.GetSelection()  
144          while item.IsOk():          while item.IsOk():
145              object = tree.GetPyData(item)              object = self.GetPyData(item)
146              if isinstance(object, Layer) or isinstance(object, Map):              if isinstance(object, Layer) or isinstance(object, Map):
147                  break                  break
148              item = tree.GetItemParent(item)              item = self.GetItemParent(item)
149    
150          self.changing_selection = 1          self.changing_selection = 1
151          try:          try:
152              self.tree.SelectItem(item)              self.SelectItem(item)
153          finally:          finally:
154              self.changing_selection = 0              self.changing_selection = 0
155    
156      def SelectedLayer(self):      def SelectedLayer(self):
157          """Return the layer object currently selected in the tree.          """Return the layer object currently selected in the tree.
158          Return None if no layer is selected"""          Return None if no layer is selected"""
159          tree = self.tree          layer = self.GetPyData(self.GetSelection())
         layer = tree.GetPyData(tree.GetSelection())  
160          if isinstance(layer, Layer):          if isinstance(layer, Layer):
161              return layer              return layer
162          return None          return None
# Line 136  class myTreeCtrlPanel(wxPanel): Line 167  class myTreeCtrlPanel(wxPanel):
167              # self.normalize_selection(). ignore the event.              # self.normalize_selection(). ignore the event.
168              return              return
169          self.normalize_selection()          self.normalize_selection()
170          layer = self.SelectedLayer()          # SelectedLayer returns None if no layer is selected. Since
171          if layer is not None:          # passing None to interactor.SelectLayer deselects the layer we
172              self.app.interactor.SelectLayer(layer)          # can simply pass the result of SelectedLayer on in all cases
173            self.app.interactor.SelectLayer(self.SelectedLayer())
174    
175      def layer_selected(self, layer):      def layer_selected(self, layer):
176          pass          item = self.layer_to_item.get(id(layer))
177            if item is not None and item != self.GetSelection():
178                self.SelectItem(item)
179    
180    
181    class SessionTreeView(NonModalDialog):
182    
183        """Non modal dialog showing the session as a tree"""
184    
185        def __init__(self, parent, app, name):
186            NonModalDialog.__init__(self, parent, app.interactor, name, "Session")
187            self.tree = SessionTreeCtrl(self, -1, app)
188    
189        def OnClose(self, event):
190            #self.interactor.Unsubscribe(SELECTED_SHAPE, self.select_shape)
191            NonModalDialog.OnClose(self, event)
192    
193            # if there were a way to get notified when the tree control
194            # itself is destroyed we could use that to unsubscribe instead
195            # of doing it here. (EVT_WINDOW_DESTROY doesn't seem to sent at
196            # all)
197            self.tree.unsubscribe_all()

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26