/[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 104 by jan, Fri Apr 19 14:46:08 2002 UTC revision 218 by bh, Thu Jul 18 12:54:48 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 MAPS_CHANGED, MAP_PROJECTION_CHANGED, \
17       LAYERS_CHANGED, LAYER_LEGEND_CHANGED, LAYER_VISIBILITY_CHANGED       LAYERS_CHANGED, LAYER_LEGEND_CHANGED, LAYER_VISIBILITY_CHANGED, \
18         EXTENSIONS_CHANGED, EXTENSION_OBJECTS_CHANGED
19  from Thuban.Model.layer import Layer, shapetype_names  from Thuban.Model.layer import Layer, shapetype_names
20  from Thuban.Model.map import Map  from Thuban.Model.map import Map
21    
22  from dialogs import NonModalDialog  from dialogs import NonModalDialog
23  from messages import SESSION_CHANGED, SELECTED_LAYER  from messages import SESSION_CHANGED, SELECTED_LAYER
24    
 def color_string(color):  
     if color is None:  
         return "None"  
     return "(%.3f, %.3f, %.3f)" % (color.red, color.green, color.blue)  
   
25    
26  class SessionTreeCtrl(wxTreeCtrl):  class SessionTreeCtrl(wxTreeCtrl):
27    
28        """Widget to display a tree view of the session.
29    
30        The tree view is created recursively from the session object. The
31        tree view calls the session's TreeInfo method which should return a
32        pair (<title>, <item>) where <title> ist the title of the session
33        item in the tree view and <items> is a list of objects to use as the
34        children of the session in the tree view.
35    
36        The items list can contain three types of items:
37    
38           1. a string. The string is used as the title for a leaf item in
39              the tree view.
40    
41           2. an object with a TreeInfo method. This method is called and
42              should return a pair just like the session's TreeInfo method.
43    
44           3. a pair (<title>, <item>) which is treated like the return
45              value of TreeInfo.
46        """
47    
48        # the session channels to subscribe to update the tree
49        session_channels = (MAPS_CHANGED, MAP_PROJECTION_CHANGED,
50                            LAYERS_CHANGED, LAYER_LEGEND_CHANGED,
51                            LAYER_VISIBILITY_CHANGED, EXTENSIONS_CHANGED,
52                            EXTENSION_OBJECTS_CHANGED)
53    
54      def __init__(self, parent, ID, app):      def __init__(self, parent, ID, app):
55          # 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.
56          wxTreeCtrl.__init__(self, parent, ID)          wxTreeCtrl.__init__(self, parent, ID)
# Line 41  class SessionTreeCtrl(wxTreeCtrl): Line 65  class SessionTreeCtrl(wxTreeCtrl):
65    
66          self.app.Subscribe(SESSION_CHANGED, self.session_changed)          self.app.Subscribe(SESSION_CHANGED, self.session_changed)
67          self.app.interactor.Subscribe(SELECTED_LAYER, self.layer_selected)          self.app.interactor.Subscribe(SELECTED_LAYER, self.layer_selected)
68    
69            # the session currently displayed in the tree
70            self.session = None
71    
72          # pretend the session has changed to build the initial tree          # pretend the session has changed to build the initial tree
73          self.session_changed()          self.session_changed()
74    
75          EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)          EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
76    
77        def unsubscribe_all(self):
78            if self.session is not None:
79                for channel in self.session_channels:
80                    self.session.Unsubscribe(channel, self.update_tree)
81                self.session = None
82            self.app.Unsubscribe(SESSION_CHANGED, self.session_changed)
83            self.app.interactor.Unsubscribe(SELECTED_LAYER, self.layer_selected)
84    
85      def update_tree(self, *args):      def update_tree(self, *args):
86          """Clear and rebuild the tree"""          """Clear and rebuild the tree"""
87          self.DeleteAllItems()          self.DeleteAllItems()
         session = self.app.session  
         root = self.AddRoot("Session: %s" % session.title)  
88          self.layer_to_item.clear()          self.layer_to_item.clear()
89          if session.filename == None:  
90              self.AppendItem(root, "Filename:")          session = self.app.session
91          else:          info = session.TreeInfo()
92              self.AppendItem(root, "Filename: %s" % session.filename)          root = self.AddRoot(info[0])
93          if session.WasModified():          self.add_items(root, info[1])
             self.AppendItem(root, "Modified: yes")  
         else:  
             self.AppendItem(root, "Modified: no")  
   
         for map in session.Maps():  
             mapitem = self.AppendItem(root, "Map: %s" % map.title)  
             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)  
                 self.layer_to_item[id(layer)] = layeritem  
                 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)  
94          self.Expand(root)          self.Expand(root)
95            # select the selected layer
96            selected_layer = self.app.interactor.selected_layer
97            if selected_layer is not None:
98                # One would expect that the selected_layer's id is in
99                # layer_to_item at this point as we've just rebuilt that
100                # mapping completely. However, when a new session is loaded
101                # for instance, it can happen that the tree view is updated
102                # before the interactor in which case selected_layer may be
103                # a layer of the old session.
104                item = self.layer_to_item.get(id(selected_layer))
105                if item is not None:
106                    self.SelectItem(item)
107    
108        def add_items(self, parent, items):
109            for item in items:
110                if hasattr(item, "TreeInfo"):
111                    # Supports the TreeInfo protocol
112                    info = item.TreeInfo()
113                    treeitem = self.AppendItem(parent, info[0])
114                    self.SetPyData(treeitem, item)
115                    self.add_items(treeitem, info[1])
116                    self.Expand(treeitem)
117                    if isinstance(item, Layer):
118                        self.layer_to_item[id(item)] = treeitem
119                elif isinstance(item, StringType):
120                    # it's a string
121                    # FIXME: What to do about UNICODE
122                    self.AppendItem(parent, item)
123                else:
124                    # assume its a sequence (title, items)
125                    treeitem = self.AppendItem(parent, item[0])
126                    self.add_items(treeitem, item[1])
127                    self.Expand(treeitem)
128    
129      def session_changed(self, *args):      def session_changed(self, *args):
130          for channel in (MAPS_CHANGED,          new_session = self.app.session
131                          MAP_PROJECTION_CHANGED,          # if the session has changed subscribe/unsubscribe
132                          LAYERS_CHANGED,          if self.session is not new_session:
133                          LAYER_LEGEND_CHANGED,              if self.session is not None:
134                          LAYER_VISIBILITY_CHANGED):                  for channel in self.session_channels:
135              self.app.session.Subscribe(channel, self.update_tree)                      self.session.Unsubscribe(channel, self.update_tree)
136                if new_session is not None:
137                    for channel in self.session_channels:
138                        new_session.Subscribe(channel, self.update_tree)
139                self.session = new_session
140          self.update_tree()          self.update_tree()
141    
142      def normalize_selection(self):      def normalize_selection(self):
# Line 162  class SessionTreeView(NonModalDialog): Line 191  class SessionTreeView(NonModalDialog):
191          #self.interactor.Unsubscribe(SELECTED_SHAPE, self.select_shape)          #self.interactor.Unsubscribe(SELECTED_SHAPE, self.select_shape)
192          NonModalDialog.OnClose(self, event)          NonModalDialog.OnClose(self, event)
193    
194            # if there were a way to get notified when the tree control
195            # itself is destroyed we could use that to unsubscribe instead
196            # of doing it here. (EVT_WINDOW_DESTROY doesn't seem to sent at
197            # all)
198            self.tree.unsubscribe_all()

Legend:
Removed from v.104  
changed lines
  Added in v.218

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26