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

Legend:
Removed from v.6  
changed lines
  Added in v.198

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26