/[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 217 - (show annotations)
Wed Jul 17 10:50:40 2002 UTC (22 years, 7 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/tree.py
File MIME type: text/x-python
File size: 7202 byte(s)
* Thuban/UI/tree.py (color_string): Removed. No longer used.
(SessionTreeCtrl.update_tree, SessionTreeCtrl.add_items): Split
update_tree into update_tree and add_items. The tree now uses a
more generic way to display the contents of the tree.
(SessionTreeCtrl): Add a doc string explaining the TreeInfo method

* Thuban/Model/layer.py (Layer.TreeInfo),
Thuban/Model/extension.py (Extension.TreeInfo),
Thuban/Model/map.py (Map.TreeInfo),
Thuban/Model/session.py (Session.TreeInfo):
Add TreeInfo methods to implement the new tree view update scheme

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 types import StringType
13
14 from wxPython.wx import *
15
16 from Thuban.Model.messages import MAPS_CHANGED, MAP_PROJECTION_CHANGED, \
17 LAYERS_CHANGED, LAYER_LEGEND_CHANGED, LAYER_VISIBILITY_CHANGED, \
18 EXTENSIONS_CHANGED, EXTENSION_OBJECTS_CHANGED
19 from Thuban.Model.layer import Layer, shapetype_names
20 from Thuban.Model.map import Map
21
22 from dialogs import NonModalDialog
23 from messages import SESSION_CHANGED, SELECTED_LAYER
24
25
26 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):
55 # Use the WANTS_CHARS style so the panel doesn't eat the Return key.
56 wxTreeCtrl.__init__(self, parent, ID)
57
58 self.app = app
59 # boolean to indicate that we manipulate the selection ourselves
60 # so that we can ignore the selection events generated
61 self.changing_selection = 0
62
63 # Dictionary mapping layer id's to tree items
64 self.layer_to_item = {}
65
66 self.app.Subscribe(SESSION_CHANGED, self.session_changed)
67 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
73 self.session_changed()
74
75 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):
86 """Clear and rebuild the tree"""
87 self.DeleteAllItems()
88 self.layer_to_item.clear()
89
90 session = self.app.session
91 info = session.TreeInfo()
92 root = self.AddRoot(info[0])
93 self.add_items(root, info[1])
94 self.Expand(root)
95 # select the selected layer
96 selected_layer = self.app.interactor.selected_layer
97 if selected_layer is not None:
98 self.SelectItem(self.layer_to_item[id(selected_layer)])
99
100 def add_items(self, parent, items):
101 for item in items:
102 if hasattr(item, "TreeInfo"):
103 # Supports the TreeInfo protocol
104 info = item.TreeInfo()
105 treeitem = self.AppendItem(parent, info[0])
106 self.SetPyData(treeitem, item)
107 self.add_items(treeitem, info[1])
108 self.Expand(treeitem)
109 if isinstance(item, Layer):
110 self.layer_to_item[id(item)] = treeitem
111 elif isinstance(item, StringType):
112 # it's a string
113 # FIXME: What to do about UNICODE
114 self.AppendItem(parent, item)
115 else:
116 # assume its a sequence (title, items)
117 treeitem = self.AppendItem(parent, item[0])
118 self.add_items(treeitem, item[1])
119 self.Expand(treeitem)
120
121 def session_changed(self, *args):
122 new_session = self.app.session
123 # if the session has changed subscribe/unsubscribe
124 if self.session is not new_session:
125 if self.session is not None:
126 for channel in self.session_channels:
127 self.session.Unsubscribe(channel, self.update_tree)
128 if new_session is not None:
129 for channel in self.session_channels:
130 new_session.Subscribe(channel, self.update_tree)
131 self.session = new_session
132 self.update_tree()
133
134 def normalize_selection(self):
135 """Select the layer or map containing currently selected item"""
136 item = self.GetSelection()
137 while item.IsOk():
138 object = self.GetPyData(item)
139 if isinstance(object, Layer) or isinstance(object, Map):
140 break
141 item = self.GetItemParent(item)
142
143 self.changing_selection = 1
144 try:
145 self.SelectItem(item)
146 finally:
147 self.changing_selection = 0
148
149 def SelectedLayer(self):
150 """Return the layer object currently selected in the tree.
151 Return None if no layer is selected"""
152 layer = self.GetPyData(self.GetSelection())
153 if isinstance(layer, Layer):
154 return layer
155 return None
156
157 def OnSelChanged(self, event):
158 if self.changing_selection:
159 # we're changing the selection ourselves (probably through
160 # self.normalize_selection(). ignore the event.
161 return
162 self.normalize_selection()
163 # SelectedLayer returns None if no layer is selected. Since
164 # passing None to interactor.SelectLayer deselects the layer we
165 # can simply pass the result of SelectedLayer on in all cases
166 self.app.interactor.SelectLayer(self.SelectedLayer())
167
168 def layer_selected(self, layer):
169 item = self.layer_to_item.get(id(layer))
170 if item is not None and item != self.GetSelection():
171 self.SelectItem(item)
172
173
174 class SessionTreeView(NonModalDialog):
175
176 """Non modal dialog showing the session as a tree"""
177
178 def __init__(self, parent, app, name):
179 NonModalDialog.__init__(self, parent, app.interactor, name, "Session")
180 self.tree = SessionTreeCtrl(self, -1, app)
181
182 def OnClose(self, event):
183 #self.interactor.Unsubscribe(SELECTED_SHAPE, self.select_shape)
184 NonModalDialog.OnClose(self, event)
185
186 # if there were a way to get notified when the tree control
187 # itself is destroyed we could use that to unsubscribe instead
188 # of doing it here. (EVT_WINDOW_DESTROY doesn't seem to sent at
189 # all)
190 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