/[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 510 - (show annotations)
Tue Mar 11 16:05:18 2003 UTC (21 years, 11 months ago) by jonathan
Original Path: trunk/thuban/Thuban/UI/tree.py
File MIME type: text/x-python
File size: 8509 byte(s)
Fixed problem with unwanted tree item images under Windows.

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, UnicodeType
13
14 from wxPython.wx import *
15
16 from Thuban import _
17 from Thuban.UI.common import *
18
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
24
25 from dialogs import NonModalDialog
26 from messages import SESSION_REPLACED, SELECTED_LAYER
27
28 BMP_SIZE = 15
29
30 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):
53
54 # Use the WANTS_CHARS style so the panel doesn't eat the Return key.
55 wxTreeCtrl.__init__(self, parent, ID)
56
57 self.app = app
58 # boolean to indicate that we manipulate the selection ourselves
59 # so that we can ignore the selection events generated
60 self.changing_selection = 0
61
62 # Dictionary mapping layer id's to tree items
63 self.layer_to_item = {}
64
65 self.app.Subscribe(SESSION_REPLACED, self.session_changed)
66 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
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 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):
85 """Clear and rebuild the tree"""
86 self.DeleteAllItems()
87 self.layer_to_item.clear()
88 self.image_list = wxImageList(BMP_SIZE, BMP_SIZE, False, 0)
89 self.AssignImageList(self.image_list)
90 #bmp = wxEmptyBitmap(BMP_SIZE, BMP_SIZE)
91 #self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
92
93 session = self.app.session
94 info = session.TreeInfo()
95 root = self.AddRoot(info[0], -2, -1, None)
96 self.add_items(root, info[1])
97 self.Expand(root)
98 # select the selected layer
99 selected_layer = self.app.interactor.selected_layer
100 if selected_layer is not None:
101 # One would expect that the selected_layer's id is in
102 # layer_to_item at this point as we've just rebuilt that
103 # mapping completely. However, when a new session is loaded
104 # for instance, it can happen that the tree view is updated
105 # before the interactor in which case selected_layer may be
106 # a layer of the old session.
107 item = self.layer_to_item.get(id(selected_layer))
108 if item is not None:
109 self.SelectItem(item)
110
111 def add_items(self, parent, items):
112
113 if items is None: return
114
115 for item in items:
116 if hasattr(item, "TreeInfo"):
117 # Supports the TreeInfo protocol
118 info = item.TreeInfo()
119 #treeitem = self.AppendItem(parent, info[0])
120 treeitem = self.AppendItem(parent, info[0], -2, -1, None)
121 self.SetPyData(treeitem, item)
122 self.add_items(treeitem, info[1])
123 self.Expand(treeitem)
124 if isinstance(item, Layer):
125 self.layer_to_item[id(item)] = treeitem
126 elif isinstance(item, StringType) or \
127 isinstance(item, UnicodeType):
128 # it's a string
129 treeitem = self.AppendItem(parent, item, -2, -1, None)
130 #self.SetItemImage(treeitem, -1)
131 else:
132 # assume its a sequence (title, items)
133 if isinstance(item[1], Color):
134
135 treeitem = self.AppendItem(parent, "(%s)" % item[0])
136
137 bmp = wxEmptyBitmap(BMP_SIZE, BMP_SIZE)
138 brush = wxBrush(Color2wxColour(item[1]), wxSOLID)
139 dc = wxMemoryDC()
140 dc.SelectObject(bmp)
141 dc.SetBrush(brush)
142 dc.Clear()
143 dc.DrawRoundedRectangle(0, 0,
144 bmp.GetWidth(), bmp.GetHeight(),
145 4)
146 dc.SelectObject(wxNullBitmap)
147
148 i = self.image_list.Add(bmp)
149 self.SetItemImage(treeitem, i)
150 else:
151 #treeitem = self.AppendItem(parent, item[0])
152 treeitem = self.AppendItem(parent, item[0], -2, -1, None)
153 self.add_items(treeitem, item[1])
154 self.Expand(treeitem)
155
156 def session_changed(self, *args):
157 new_session = self.app.session
158 # if the session has changed subscribe/unsubscribe
159 if self.session is not new_session:
160 if self.session is not None:
161 self.session.Unsubscribe(CHANGED, self.update_tree)
162 if new_session is not None:
163 new_session.Subscribe(CHANGED, self.update_tree)
164 self.session = new_session
165 self.update_tree()
166
167 def normalize_selection(self):
168 """Select the layer or map containing currently selected item"""
169 item = self.GetSelection()
170 while item.IsOk():
171 object = self.GetPyData(item)
172 if isinstance(object, Layer) or isinstance(object, Map):
173 break
174 item = self.GetItemParent(item)
175 else:
176 # No layer or map was found in the chain of parents, so
177 # there's nothing we can do.
178 return
179
180 self.changing_selection = 1
181 try:
182 self.SelectItem(item)
183 finally:
184 self.changing_selection = 0
185
186 def SelectedLayer(self):
187 """Return the layer object currently selected in the tree.
188 Return None if no layer is selected"""
189 layer = self.GetPyData(self.GetSelection())
190 if isinstance(layer, Layer):
191 return layer
192 return None
193
194 def OnSelChanged(self, event):
195 if self.changing_selection:
196 # we're changing the selection ourselves (probably through
197 # self.normalize_selection(). ignore the event.
198 return
199 self.normalize_selection()
200 # SelectedLayer returns None if no layer is selected. Since
201 # passing None to interactor.SelectLayer deselects the layer we
202 # can simply pass the result of SelectedLayer on in all cases
203 self.app.interactor.SelectLayer(self.SelectedLayer())
204
205 def layer_selected(self, layer):
206 item = self.layer_to_item.get(id(layer))
207 if item is not None and item != self.GetSelection():
208 self.SelectItem(item)
209
210
211 class SessionTreeView(NonModalDialog):
212
213 """Non modal dialog showing the session as a tree"""
214
215 def __init__(self, parent, app, name):
216 NonModalDialog.__init__(self, parent, app.interactor, name,
217 _("Session"))
218 self.tree = SessionTreeCtrl(self, -1, app)
219
220 def OnClose(self, event):
221 NonModalDialog.OnClose(self, event)
222
223 # if there were a way to get notified when the tree control
224 # itself is destroyed we could use that to unsubscribe instead
225 # of doing it here. (EVT_WINDOW_DESTROY doesn't seem to sent at
226 # all)
227 self.tree.unsubscribe_all()
228

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26