/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/tree.py
ViewVC logotype

Contents of /branches/WIP-pyshapelib-bramz/Thuban/UI/tree.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 161 - (show annotations)
Wed May 8 13:47:10 2002 UTC (22 years, 10 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/tree.py
File MIME type: text/x-python
File size: 7973 byte(s)
	* Thuban/UI/tree.py (SessionTreeCtrl.unsubscribe_all): Remove a
	debug print and set session to None after unsubscribing

1 #! /usr/bin/python
2 # Copyright (c) 2001, 2002 by Intevation GmbH
3 # Authors:
4 # Jan-Oliver Wagner <[email protected]>
5 # Bernhard Herzog <[email protected]>
6 #
7 # This program is free software under the GPL (>=v2)
8 # Read the file COPYING coming with Thuban for details.
9
10 __version__ = "$Revision$"
11
12 from wxPython.wx import *
13
14 from Thuban.Model.messages import MAPS_CHANGED, MAP_PROJECTION_CHANGED, \
15 LAYERS_CHANGED, LAYER_LEGEND_CHANGED, LAYER_VISIBILITY_CHANGED
16 from Thuban.Model.layer import Layer, shapetype_names
17 from Thuban.Model.map import Map
18
19 from dialogs import NonModalDialog
20 from messages import SESSION_CHANGED, SELECTED_LAYER
21
22 def color_string(color):
23 if color is None:
24 return "None"
25 return "(%.3f, %.3f, %.3f)" % (color.red, color.green, color.blue)
26
27
28 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.
37 wxTreeCtrl.__init__(self, parent, ID)
38
39 self.app = app
40 # boolean to indicate that we manipulate the selection ourselves
41 # so that we can ignore the selection events generated
42 self.changing_selection = 0
43
44 # Dictionary mapping layer id's to tree items
45 self.layer_to_item = {}
46
47 self.app.Subscribe(SESSION_CHANGED, self.session_changed)
48 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
54 self.session_changed()
55
56 EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
57
58 def unsubscribe_all(self):
59 if self.session is not None:
60 for channel in self.session_channels:
61 self.session.Unsubscribe(channel, self.update_tree)
62 self.session = None
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):
67 """Clear and rebuild the tree"""
68 self.DeleteAllItems()
69 session = self.app.session
70 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():
82 mapitem = self.AppendItem(root, "Map: %s" % map.title)
83 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:
88 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:
93 parameteritem = self.AppendItem(projectionitem, str(param))
94 self.Expand(projectionitem)
95
96 layers = map.Layers()
97 for layer_index in range(len(layers) - 1, -1, -1):
98 layer = layers[layer_index]
99 idata = wxTreeItemData()
100 idata.SetData(layer)
101 layeritem = self.AppendItem(mapitem,
102 "Layer '%s'" % layer.Title(),
103 data = idata)
104 self.layer_to_item[id(layer)] = layeritem
105 if layer is self.app.interactor.selected_layer:
106 self.SelectItem(layeritem)
107 if isinstance(layer, Layer):
108 if layer.Visible():
109 text = "Shown"
110 else:
111 text = "Hidden"
112 self.AppendItem(layeritem, text)
113 self.AppendItem(layeritem, "Shapes: %d" %layer.NumShapes())
114 self.AppendItem(layeritem,
115 ("Extent (lat-lon): (%g, %g, %g, %g)"
116 % layer.LatLongBoundingBox()))
117 self.AppendItem(layeritem,
118 "Shapetype: %s"
119 % shapetype_names[layer.ShapeType()])
120 self.AppendItem(layeritem,
121 "Fill: " + color_string(layer.fill))
122 self.AppendItem(layeritem,
123 "Outline: " + color_string(layer.stroke))
124 self.Expand(layeritem)
125 self.Expand(mapitem)
126 self.Expand(root)
127
128 def session_changed(self, *args):
129 new_session = self.app.session
130 # if the session has changed subscribe/unsubscribe
131 if self.session is not new_session:
132 if self.session is not None:
133 for channel in self.session_channels:
134 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()
140
141 def normalize_selection(self):
142 """Select the layer or map containing currently selected item"""
143 item = self.GetSelection()
144 while item.IsOk():
145 object = self.GetPyData(item)
146 if isinstance(object, Layer) or isinstance(object, Map):
147 break
148 item = self.GetItemParent(item)
149
150 self.changing_selection = 1
151 try:
152 self.SelectItem(item)
153 finally:
154 self.changing_selection = 0
155
156 def SelectedLayer(self):
157 """Return the layer object currently selected in the tree.
158 Return None if no layer is selected"""
159 layer = self.GetPyData(self.GetSelection())
160 if isinstance(layer, Layer):
161 return layer
162 return None
163
164 def OnSelChanged(self, event):
165 if self.changing_selection:
166 # we're changing the selection ourselves (probably through
167 # self.normalize_selection(). ignore the event.
168 return
169 self.normalize_selection()
170 # SelectedLayer returns None if no layer is selected. Since
171 # passing None to interactor.SelectLayer deselects the layer we
172 # 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):
176 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()

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26