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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 217 - (hide 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 bh 6 #! /usr/bin/python
2 bh 151 # Copyright (c) 2001, 2002 by Intevation GmbH
3 bh 6 # 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 bh 217 from types import StringType
13    
14 bh 6 from wxPython.wx import *
15    
16     from Thuban.Model.messages import MAPS_CHANGED, MAP_PROJECTION_CHANGED, \
17 jan 198 LAYERS_CHANGED, LAYER_LEGEND_CHANGED, LAYER_VISIBILITY_CHANGED, \
18     EXTENSIONS_CHANGED, EXTENSION_OBJECTS_CHANGED
19 bh 6 from Thuban.Model.layer import Layer, shapetype_names
20     from Thuban.Model.map import Map
21    
22 bh 36 from dialogs import NonModalDialog
23 bh 6 from messages import SESSION_CHANGED, SELECTED_LAYER
24    
25    
26 bh 41 class SessionTreeCtrl(wxTreeCtrl):
27 bh 36
28 bh 217 """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 jan 198 # the session channels to subscribe to update the tree
49 bh 151 session_channels = (MAPS_CHANGED, MAP_PROJECTION_CHANGED,
50     LAYERS_CHANGED, LAYER_LEGEND_CHANGED,
51 jan 198 LAYER_VISIBILITY_CHANGED, EXTENSIONS_CHANGED,
52     EXTENSION_OBJECTS_CHANGED)
53 bh 151
54 bh 36 def __init__(self, parent, ID, app):
55 bh 6 # Use the WANTS_CHARS style so the panel doesn't eat the Return key.
56 bh 36 wxTreeCtrl.__init__(self, parent, ID)
57    
58 bh 6 self.app = app
59 bh 14 # 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 bh 41 # Dictionary mapping layer id's to tree items
64     self.layer_to_item = {}
65    
66 bh 6 self.app.Subscribe(SESSION_CHANGED, self.session_changed)
67     self.app.interactor.Subscribe(SELECTED_LAYER, self.layer_selected)
68 bh 151
69     # the session currently displayed in the tree
70     self.session = None
71    
72 bh 6 # pretend the session has changed to build the initial tree
73     self.session_changed()
74    
75 bh 36 EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
76 bh 6
77 bh 151 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 bh 161 self.session = None
82 bh 151 self.app.Unsubscribe(SESSION_CHANGED, self.session_changed)
83     self.app.interactor.Unsubscribe(SELECTED_LAYER, self.layer_selected)
84    
85 bh 6 def update_tree(self, *args):
86     """Clear and rebuild the tree"""
87 bh 36 self.DeleteAllItems()
88 bh 41 self.layer_to_item.clear()
89 jan 104
90 bh 217 session = self.app.session
91     info = session.TreeInfo()
92     root = self.AddRoot(info[0])
93     self.add_items(root, info[1])
94 bh 36 self.Expand(root)
95 bh 217 # 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 bh 6
100 bh 217 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 jan 198
121 bh 6 def session_changed(self, *args):
122 bh 151 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 bh 6 self.update_tree()
133    
134     def normalize_selection(self):
135     """Select the layer or map containing currently selected item"""
136 bh 36 item = self.GetSelection()
137 bh 6 while item.IsOk():
138 bh 36 object = self.GetPyData(item)
139 bh 6 if isinstance(object, Layer) or isinstance(object, Map):
140     break
141 bh 36 item = self.GetItemParent(item)
142 bh 6
143 bh 14 self.changing_selection = 1
144     try:
145 bh 36 self.SelectItem(item)
146 bh 14 finally:
147     self.changing_selection = 0
148 bh 6
149     def SelectedLayer(self):
150     """Return the layer object currently selected in the tree.
151     Return None if no layer is selected"""
152 bh 36 layer = self.GetPyData(self.GetSelection())
153 bh 6 if isinstance(layer, Layer):
154     return layer
155     return None
156    
157     def OnSelChanged(self, event):
158 bh 14 if self.changing_selection:
159     # we're changing the selection ourselves (probably through
160     # self.normalize_selection(). ignore the event.
161     return
162 bh 6 self.normalize_selection()
163 bh 61 # 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 bh 6
168     def layer_selected(self, layer):
169 bh 41 item = self.layer_to_item.get(id(layer))
170     if item is not None and item != self.GetSelection():
171     self.SelectItem(item)
172 bh 36
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 bh 41 self.tree = SessionTreeCtrl(self, -1, app)
181 bh 36
182     def OnClose(self, event):
183     #self.interactor.Unsubscribe(SELECTED_SHAPE, self.select_shape)
184     NonModalDialog.OnClose(self, event)
185    
186 bh 151 # 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