/[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 61 by bh, Thu Sep 13 17:58:49 2001 UTC revision 521 by jonathan, Wed Mar 12 13:18:50 2003 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, UnicodeType
13    
14  from wxPython.wx import *  from wxPython.wx import *
15    
16  from Thuban.Model.messages import MAPS_CHANGED, MAP_PROJECTION_CHANGED, \  from Thuban import _
17       LAYERS_CHANGED, LAYER_LEGEND_CHANGED, LAYER_VISIBILITY_CHANGED  from Thuban.UI.common import *
18  from Thuban.Model.layer import Layer, shapetype_names  
19    from Thuban.Model.color import Color
20    
21    from Thuban.Model.messages import CHANGED
22    from Thuban.Model.layer import Layer
23  from Thuban.Model.map import Map  from Thuban.Model.map import Map
24    
25  from dialogs import NonModalDialog  from dialogs import NonModalDialog
26  from messages import SESSION_CHANGED, SELECTED_LAYER  from messages import SESSION_REPLACED, SELECTED_LAYER
   
 def color_string(color):  
     if color is None:  
         return "None"  
     return "(%.3f, %.3f, %.3f)" % (color.red, color.green, color.blue)  
27    
28    BMP_SIZE = 15
29    
30  class SessionTreeCtrl(wxTreeCtrl):  class SessionTreeCtrl(wxTreeCtrl):
31    
32        """Widget to display a tree view of the session.
33    
34        The tree view is created recursively from the session object. The
35        tree view calls the session's TreeInfo method which should return a
36        pair (<title>, <item>) where <title> ist the title of the session
37        item in the tree view and <items> is a list of objects to use as the
38        children of the session in the tree view.
39    
40        The items list can contain three types of items:
41    
42           1. a string. The string is used as the title for a leaf item in
43              the tree view.
44    
45           2. an object with a TreeInfo method. This method is called and
46              should return a pair just like the session's TreeInfo method.
47    
48           3. a pair (<title>, <item>) which is treated like the return
49              value of TreeInfo.
50        """
51    
52      def __init__(self, parent, ID, app):      def __init__(self, parent, ID, app):
53    
54          # 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.
55          wxTreeCtrl.__init__(self, parent, ID)          wxTreeCtrl.__init__(self, parent, ID)
56    
# Line 39  class SessionTreeCtrl(wxTreeCtrl): Line 62  class SessionTreeCtrl(wxTreeCtrl):
62          # Dictionary mapping layer id's to tree items          # Dictionary mapping layer id's to tree items
63          self.layer_to_item = {}          self.layer_to_item = {}
64    
65          self.app.Subscribe(SESSION_CHANGED, self.session_changed)          self.app.Subscribe(SESSION_REPLACED, self.session_changed)
66          self.app.interactor.Subscribe(SELECTED_LAYER, self.layer_selected)          self.app.interactor.Subscribe(SELECTED_LAYER, self.layer_selected)
67    
68            # the session currently displayed in the tree
69            self.session = None
70    
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                self.session.Unsubscribe(CHANGED, self.update_tree)
80                self.session = None
81            self.app.Unsubscribe(SESSION_REPLACED, self.session_changed)
82            self.app.interactor.Unsubscribe(SELECTED_LAYER, self.layer_selected)
83    
84      def update_tree(self, *args):      def update_tree(self, *args):
85          """Clear and rebuild the tree"""          """Clear and rebuild the tree"""
86          self.DeleteAllItems()          self.DeleteAllItems()
         session = self.app.session  
         root = self.AddRoot("Session: %s" % session.title)  
87          self.layer_to_item.clear()          self.layer_to_item.clear()
88          for map in session.Maps():          self.image_list = wxImageList(BMP_SIZE, BMP_SIZE, False, 0)
89              mapitem = self.AppendItem(root, "Map: %s" % map.title)  
90              self.SetPyData(mapitem, map)          bmp = wxEmptyBitmap(BMP_SIZE, BMP_SIZE)
91              if map.projection and len(map.projection.params) > 0:          dc = wxMemoryDC()
92                  projectionitem = self.AppendItem(mapitem, "Projection")          dc.SelectObject(bmp)
93                  for param in map.projection.params:          dc.SetBrush(wxBLACK_BRUSH)
94                      parameteritem = self.AppendItem(projectionitem, str(param))          dc.Clear()
95                  self.Expand(projectionitem)          dc.SelectObject(wxNullBitmap)
96    
97              layers = map.Layers()          self.emptyImageIndex = \
98              for layer_index in range(len(layers) - 1, -1, -1):              self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
99                  layer = layers[layer_index]  
100                  idata = wxTreeItemData()          self.AssignImageList(self.image_list)
101                  idata.SetData(layer)  
102                  layeritem = self.AppendItem(mapitem,          session = self.app.session
103                                              "Layer '%s'" % layer.Title(),          info = session.TreeInfo()
104                                              data = idata)          root = self.AddRoot(info[0], -1, -1, None)
105                  self.layer_to_item[id(layer)] = layeritem          self.SetItemImage(root, self.emptyImageIndex)
106                  if layer is self.app.interactor.selected_layer:          self.add_items(root, info[1])
                     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)  
107          self.Expand(root)          self.Expand(root)
108            # select the selected layer
109            selected_layer = self.app.interactor.selected_layer
110            if selected_layer is not None:
111                # One would expect that the selected_layer's id is in
112                # layer_to_item at this point as we've just rebuilt that
113                # mapping completely. However, when a new session is loaded
114                # for instance, it can happen that the tree view is updated
115                # before the interactor in which case selected_layer may be
116                # a layer of the old session.
117                item = self.layer_to_item.get(id(selected_layer))
118                if item is not None:
119                    self.SelectItem(item)
120    
121        def add_items(self, parent, items):
122    
123            if items is None: return
124    
125            for item in items:
126                if hasattr(item, "TreeInfo"):
127                    # Supports the TreeInfo protocol
128                    info = item.TreeInfo()
129                    treeitem = self.AppendItem(parent, info[0], -1, -1, None)
130                    self.SetItemImage(treeitem, self.emptyImageIndex)
131                    self.SetPyData(treeitem, item)
132                    self.add_items(treeitem, info[1])
133                    self.Expand(treeitem)
134                    if isinstance(item, Layer):
135                        self.layer_to_item[id(item)] = treeitem
136                elif isinstance(item, StringType) or \
137                     isinstance(item, UnicodeType):
138                    # it's a string
139                    treeitem = self.AppendItem(parent, item, -1, -1, None)
140                    self.SetItemImage(treeitem, self.emptyImageIndex)
141                else:
142                    # assume its a sequence (title, items)
143                    if isinstance(item[1], Color):
144    
145                        treeitem = self.AppendItem(parent, "(%s)" % item[0])
146    
147                        bmp = wxEmptyBitmap(BMP_SIZE, BMP_SIZE)
148                        brush = wxBrush(Color2wxColour(item[1]), wxSOLID)
149                        dc = wxMemoryDC()
150                        dc.SelectObject(bmp)
151                        dc.SetBrush(brush)
152                        dc.Clear()
153                        dc.DrawRoundedRectangle(0, 0,
154                                                bmp.GetWidth(), bmp.GetHeight(),
155                                                4)
156                        dc.SelectObject(wxNullBitmap)
157    
158                        i = self.image_list.Add(bmp)
159                        self.SetItemImage(treeitem, i)
160                    else:
161                        treeitem = self.AppendItem(parent, item[0], -1, -1, None)
162                        self.SetItemImage(treeitem, self.emptyImageIndex)
163                        self.add_items(treeitem, item[1])
164                    self.Expand(treeitem)
165    
166      def session_changed(self, *args):      def session_changed(self, *args):
167          for channel in (MAPS_CHANGED,          new_session = self.app.session
168                          MAP_PROJECTION_CHANGED,          # if the session has changed subscribe/unsubscribe
169                          LAYERS_CHANGED,          if self.session is not new_session:
170                          LAYER_LEGEND_CHANGED,              if self.session is not None:
171                          LAYER_VISIBILITY_CHANGED):                  self.session.Unsubscribe(CHANGED, self.update_tree)
172              self.app.session.Subscribe(channel, self.update_tree)              if new_session is not None:
173                    new_session.Subscribe(CHANGED, self.update_tree)
174                self.session = new_session
175          self.update_tree()          self.update_tree()
176    
177      def normalize_selection(self):      def normalize_selection(self):
# Line 109  class SessionTreeCtrl(wxTreeCtrl): Line 182  class SessionTreeCtrl(wxTreeCtrl):
182              if isinstance(object, Layer) or isinstance(object, Map):              if isinstance(object, Layer) or isinstance(object, Map):
183                  break                  break
184              item = self.GetItemParent(item)              item = self.GetItemParent(item)
185            else:
186                # No layer or map was found in the chain of parents, so
187                # there's nothing we can do.
188                return
189    
190          self.changing_selection = 1          self.changing_selection = 1
191          try:          try:
# Line 146  class SessionTreeView(NonModalDialog): Line 223  class SessionTreeView(NonModalDialog):
223      """Non modal dialog showing the session as a tree"""      """Non modal dialog showing the session as a tree"""
224    
225      def __init__(self, parent, app, name):      def __init__(self, parent, app, name):
226          NonModalDialog.__init__(self, parent, app.interactor, name, "Session")          NonModalDialog.__init__(self, parent, app.interactor, name,
227                                    _("Session"))
228          self.tree = SessionTreeCtrl(self, -1, app)          self.tree = SessionTreeCtrl(self, -1, app)
229    
230      def OnClose(self, event):      def OnClose(self, event):
         #self.interactor.Unsubscribe(SELECTED_SHAPE, self.select_shape)  
231          NonModalDialog.OnClose(self, event)          NonModalDialog.OnClose(self, event)
232    
233            # if there were a way to get notified when the tree control
234            # itself is destroyed we could use that to unsubscribe instead
235            # of doing it here. (EVT_WINDOW_DESTROY doesn't seem to sent at
236            # all)
237            self.tree.unsubscribe_all()
238    

Legend:
Removed from v.61  
changed lines
  Added in v.521

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26