/[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 36 by bh, Thu Sep 6 17:16:06 2001 UTC revision 233 by bh, Fri Jul 19 15:15:16 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 9  Line 9 
9    
10  __version__ = "$Revision$"  __version__ = "$Revision$"
11    
12    from types import StringType
13    
14  from wxPython.wx import *  from wxPython.wx import *
15    
16  from Thuban.Model.messages import MAPS_CHANGED, MAP_PROJECTION_CHANGED, \  from Thuban.Model.messages import CHANGED
17       LAYERS_CHANGED, LAYER_LEGEND_CHANGED, LAYER_VISIBILITY_CHANGED  from Thuban.Model.layer import Layer
 from Thuban.Model.layer import Layer, shapetype_names  
18  from Thuban.Model.map import Map  from Thuban.Model.map import Map
19    
20  from dialogs import NonModalDialog  from dialogs import NonModalDialog
21  from messages import SESSION_CHANGED, SELECTED_LAYER  from messages import SESSION_CHANGED, SELECTED_LAYER
22    
 def color_string(color):  
     if color is None:  
         return "None"  
     return "(%.3f, %.3f, %.3f)" % (color.red, color.green, color.blue)  
23    
24    class SessionTreeCtrl(wxTreeCtrl):
25    
26        """Widget to display a tree view of the session.
27    
28        The tree view is created recursively from the session object. The
29        tree view calls the session's TreeInfo method which should return a
30        pair (<title>, <item>) where <title> ist the title of the session
31        item in the tree view and <items> is a list of objects to use as the
32        children of the session in the tree view.
33    
34        The items list can contain three types of items:
35    
36           1. a string. The string is used as the title for a leaf item in
37              the tree view.
38    
39           2. an object with a TreeInfo method. This method is called and
40              should return a pair just like the session's TreeInfo method.
41    
42  class SessioinTreeCtrl(wxTreeCtrl):         3. a pair (<title>, <item>) which is treated like the return
43              value of TreeInfo.
44        """
45    
46      def __init__(self, parent, ID, app):      def __init__(self, parent, ID, app):
47          # 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.
# Line 36  class SessioinTreeCtrl(wxTreeCtrl): Line 52  class SessioinTreeCtrl(wxTreeCtrl):
52          # so that we can ignore the selection events generated          # so that we can ignore the selection events generated
53          self.changing_selection = 0          self.changing_selection = 0
54    
55            # Dictionary mapping layer id's to tree items
56            self.layer_to_item = {}
57    
58          self.app.Subscribe(SESSION_CHANGED, self.session_changed)          self.app.Subscribe(SESSION_CHANGED, self.session_changed)
59          self.app.interactor.Subscribe(SELECTED_LAYER, self.layer_selected)          self.app.interactor.Subscribe(SELECTED_LAYER, self.layer_selected)
60    
61            # the session currently displayed in the tree
62            self.session = None
63    
64          # pretend the session has changed to build the initial tree          # pretend the session has changed to build the initial tree
65          self.session_changed()          self.session_changed()
66    
67          EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)          EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
68    
69        def unsubscribe_all(self):
70            if self.session is not None:
71                self.session.Unsubscribe(CHANGED, self.update_tree)
72                self.session = None
73            self.app.Unsubscribe(SESSION_CHANGED, self.session_changed)
74            self.app.interactor.Unsubscribe(SELECTED_LAYER, self.layer_selected)
75    
76      def update_tree(self, *args):      def update_tree(self, *args):
77          """Clear and rebuild the tree"""          """Clear and rebuild the tree"""
78          self.DeleteAllItems()          self.DeleteAllItems()
79            self.layer_to_item.clear()
80    
81          session = self.app.session          session = self.app.session
82          root = self.AddRoot("Session: %s" % session.title)          info = session.TreeInfo()
83          for map in session.Maps():          root = self.AddRoot(info[0])
84              mapitem = self.AppendItem(root, "Map: %s" % map.title)          self.add_items(root, info[1])
             self.SetPyData(mapitem, map)  
             if map.projection and len(map.projection.params) > 0:  
                 projectionitem = self.AppendItem(mapitem, "Projection")  
                 for param in map.projection.params:  
                     parameteritem = self.AppendItem(projectionitem, str(param))  
                 self.Expand(projectionitem)  
   
             layers = map.Layers()  
             for layer_index in range(len(layers) - 1, -1, -1):  
                 layer = layers[layer_index]  
                 idata = wxTreeItemData()  
                 idata.SetData(layer)  
                 layeritem = self.AppendItem(mapitem,  
                                             "Layer '%s'" % layer.Title(),  
                                             data = idata)  
                 if layer is self.app.interactor.selected_layer:  
                     self.SelectItem(layeritem)  
                 if isinstance(layer, Layer):  
                     if layer.Visible():  
                         text = "Shown"  
                     else:  
                         text = "Hidden"  
                     self.AppendItem(layeritem, text)  
                     self.AppendItem(layeritem, "Shapes: %d" %layer.NumShapes())  
                     self.AppendItem(layeritem, ("Extents: (%g, %g, %g, %g)"  
                                                 % layer.LatLongBoundingBox()))  
                     self.AppendItem(layeritem,  
                                     "Shapetype: %s"  
                                     % shapetype_names[layer.ShapeType()])  
                     self.AppendItem(layeritem,  
                                     "Fill: " + color_string(layer.fill))  
                     self.AppendItem(layeritem,  
                                     "Outline: " + color_string(layer.stroke))  
                 self.Expand(layeritem)  
             self.Expand(mapitem)  
85          self.Expand(root)          self.Expand(root)
86            # select the selected layer
87            selected_layer = self.app.interactor.selected_layer
88            if selected_layer is not None:
89                # One would expect that the selected_layer's id is in
90                # layer_to_item at this point as we've just rebuilt that
91                # mapping completely. However, when a new session is loaded
92                # for instance, it can happen that the tree view is updated
93                # before the interactor in which case selected_layer may be
94                # a layer of the old session.
95                item = self.layer_to_item.get(id(selected_layer))
96                if item is not None:
97                    self.SelectItem(item)
98    
99        def add_items(self, parent, items):
100            for item in items:
101                if hasattr(item, "TreeInfo"):
102                    # Supports the TreeInfo protocol
103                    info = item.TreeInfo()
104                    treeitem = self.AppendItem(parent, info[0])
105                    self.SetPyData(treeitem, item)
106                    self.add_items(treeitem, info[1])
107                    self.Expand(treeitem)
108                    if isinstance(item, Layer):
109                        self.layer_to_item[id(item)] = treeitem
110                elif isinstance(item, StringType):
111                    # it's a string
112                    # FIXME: What to do about UNICODE
113                    self.AppendItem(parent, item)
114                else:
115                    # assume its a sequence (title, items)
116                    treeitem = self.AppendItem(parent, item[0])
117                    self.add_items(treeitem, item[1])
118                    self.Expand(treeitem)
119    
120      def session_changed(self, *args):      def session_changed(self, *args):
121          for channel in (MAPS_CHANGED,          new_session = self.app.session
122                          MAP_PROJECTION_CHANGED,          # if the session has changed subscribe/unsubscribe
123                          LAYERS_CHANGED,          if self.session is not new_session:
124                          LAYER_LEGEND_CHANGED,              if self.session is not None:
125                          LAYER_VISIBILITY_CHANGED):                  self.session.Unsubscribe(CHANGED, self.update_tree)
126              self.app.session.Subscribe(channel, self.update_tree)              if new_session is not None:
127                    new_session.Subscribe(CHANGED, self.update_tree)
128                self.session = new_session
129          self.update_tree()          self.update_tree()
130    
131      def normalize_selection(self):      def normalize_selection(self):
# Line 125  class SessioinTreeCtrl(wxTreeCtrl): Line 157  class SessioinTreeCtrl(wxTreeCtrl):
157              # self.normalize_selection(). ignore the event.              # self.normalize_selection(). ignore the event.
158              return              return
159          self.normalize_selection()          self.normalize_selection()
160          layer = self.SelectedLayer()          # SelectedLayer returns None if no layer is selected. Since
161          if layer is not None:          # passing None to interactor.SelectLayer deselects the layer we
162              self.app.interactor.SelectLayer(layer)          # can simply pass the result of SelectedLayer on in all cases
163            self.app.interactor.SelectLayer(self.SelectedLayer())
164    
165      def layer_selected(self, layer):      def layer_selected(self, layer):
166          pass          item = self.layer_to_item.get(id(layer))
167            if item is not None and item != self.GetSelection():
168                self.SelectItem(item)
169    
170    
171  class SessionTreeView(NonModalDialog):  class SessionTreeView(NonModalDialog):
# Line 139  class SessionTreeView(NonModalDialog): Line 174  class SessionTreeView(NonModalDialog):
174    
175      def __init__(self, parent, app, name):      def __init__(self, parent, app, name):
176          NonModalDialog.__init__(self, parent, app.interactor, name, "Session")          NonModalDialog.__init__(self, parent, app.interactor, name, "Session")
177          self.tree = SessioinTreeCtrl(self, -1, app)          self.tree = SessionTreeCtrl(self, -1, app)
178    
179      def OnClose(self, event):      def OnClose(self, event):
180          #self.interactor.Unsubscribe(SELECTED_SHAPE, self.select_shape)          #self.interactor.Unsubscribe(SELECTED_SHAPE, self.select_shape)
181          NonModalDialog.OnClose(self, event)          NonModalDialog.OnClose(self, event)
182    
183            # if there were a way to get notified when the tree control
184            # itself is destroyed we could use that to unsubscribe instead
185            # of doing it here. (EVT_WINDOW_DESTROY doesn't seem to sent at
186            # all)
187            self.tree.unsubscribe_all()

Legend:
Removed from v.36  
changed lines
  Added in v.233

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26