/[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 521 - (hide annotations)
Wed Mar 12 13:18:50 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: 8775 byte(s)
Create an empty image to use when there is no special image for an item.

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 jonathan 383 from types import StringType, UnicodeType
13 bh 217
14 bh 6 from wxPython.wx import *
15    
16 jan 374 from Thuban import _
17 jonathan 443 from Thuban.UI.common import *
18 jan 374
19 jonathan 383 from Thuban.Model.color import Color
20    
21 bh 233 from Thuban.Model.messages import CHANGED
22     from Thuban.Model.layer import Layer
23 bh 6 from Thuban.Model.map import Map
24    
25 bh 36 from dialogs import NonModalDialog
26 jonathan 504 from messages import SESSION_REPLACED, SELECTED_LAYER
27 bh 6
28 jonathan 383 BMP_SIZE = 15
29 bh 6
30 bh 41 class SessionTreeCtrl(wxTreeCtrl):
31 bh 36
32 bh 217 """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 bh 36 def __init__(self, parent, ID, app):
53 jonathan 383
54 bh 6 # Use the WANTS_CHARS style so the panel doesn't eat the Return key.
55 bh 36 wxTreeCtrl.__init__(self, parent, ID)
56    
57 bh 6 self.app = app
58 bh 14 # 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 bh 41 # Dictionary mapping layer id's to tree items
63     self.layer_to_item = {}
64    
65 jonathan 504 self.app.Subscribe(SESSION_REPLACED, self.session_changed)
66 bh 6 self.app.interactor.Subscribe(SELECTED_LAYER, self.layer_selected)
67 bh 151
68     # the session currently displayed in the tree
69     self.session = None
70    
71 jonathan 383
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 bh 233 self.session.Unsubscribe(CHANGED, self.update_tree)
80 bh 161 self.session = None
81 jonathan 504 self.app.Unsubscribe(SESSION_REPLACED, self.session_changed)
82 bh 151 self.app.interactor.Unsubscribe(SELECTED_LAYER, self.layer_selected)
83    
84 bh 6 def update_tree(self, *args):
85     """Clear and rebuild the tree"""
86 bh 36 self.DeleteAllItems()
87 bh 41 self.layer_to_item.clear()
88 jonathan 510 self.image_list = wxImageList(BMP_SIZE, BMP_SIZE, False, 0)
89 jonathan 521
90     bmp = wxEmptyBitmap(BMP_SIZE, BMP_SIZE)
91     dc = wxMemoryDC()
92     dc.SelectObject(bmp)
93     dc.SetBrush(wxBLACK_BRUSH)
94     dc.Clear()
95     dc.SelectObject(wxNullBitmap)
96    
97     self.emptyImageIndex = \
98     self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
99    
100 jonathan 510 self.AssignImageList(self.image_list)
101 jan 104
102 bh 217 session = self.app.session
103     info = session.TreeInfo()
104 jonathan 521 root = self.AddRoot(info[0], -1, -1, None)
105     self.SetItemImage(root, self.emptyImageIndex)
106 bh 217 self.add_items(root, info[1])
107 bh 36 self.Expand(root)
108 bh 217 # select the selected layer
109     selected_layer = self.app.interactor.selected_layer
110     if selected_layer is not None:
111 bh 218 # 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 bh 6
121 bh 217 def add_items(self, parent, items):
122 jonathan 383
123     if items is None: return
124    
125 bh 217 for item in items:
126     if hasattr(item, "TreeInfo"):
127     # Supports the TreeInfo protocol
128     info = item.TreeInfo()
129 jonathan 521 treeitem = self.AppendItem(parent, info[0], -1, -1, None)
130     self.SetItemImage(treeitem, self.emptyImageIndex)
131 bh 217 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 jonathan 383 elif isinstance(item, StringType) or \
137     isinstance(item, UnicodeType):
138 bh 217 # it's a string
139 jonathan 521 treeitem = self.AppendItem(parent, item, -1, -1, None)
140     self.SetItemImage(treeitem, self.emptyImageIndex)
141 bh 217 else:
142     # assume its a sequence (title, items)
143 jonathan 383 if isinstance(item[1], Color):
144    
145 jonathan 417 treeitem = self.AppendItem(parent, "(%s)" % item[0])
146    
147 jonathan 383 bmp = wxEmptyBitmap(BMP_SIZE, BMP_SIZE)
148 jonathan 443 brush = wxBrush(Color2wxColour(item[1]), wxSOLID)
149 jonathan 383 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 jonathan 521 treeitem = self.AppendItem(parent, item[0], -1, -1, None)
162     self.SetItemImage(treeitem, self.emptyImageIndex)
163 jonathan 383 self.add_items(treeitem, item[1])
164 bh 217 self.Expand(treeitem)
165 jan 198
166 bh 6 def session_changed(self, *args):
167 bh 151 new_session = self.app.session
168     # if the session has changed subscribe/unsubscribe
169     if self.session is not new_session:
170     if self.session is not None:
171 bh 233 self.session.Unsubscribe(CHANGED, self.update_tree)
172 bh 151 if new_session is not None:
173 bh 233 new_session.Subscribe(CHANGED, self.update_tree)
174 bh 151 self.session = new_session
175 bh 6 self.update_tree()
176    
177     def normalize_selection(self):
178     """Select the layer or map containing currently selected item"""
179 bh 36 item = self.GetSelection()
180 bh 6 while item.IsOk():
181 bh 36 object = self.GetPyData(item)
182 bh 6 if isinstance(object, Layer) or isinstance(object, Map):
183     break
184 bh 36 item = self.GetItemParent(item)
185 bh 353 else:
186     # No layer or map was found in the chain of parents, so
187     # there's nothing we can do.
188     return
189 bh 6
190 bh 14 self.changing_selection = 1
191     try:
192 bh 36 self.SelectItem(item)
193 bh 14 finally:
194     self.changing_selection = 0
195 bh 6
196     def SelectedLayer(self):
197     """Return the layer object currently selected in the tree.
198     Return None if no layer is selected"""
199 bh 36 layer = self.GetPyData(self.GetSelection())
200 bh 6 if isinstance(layer, Layer):
201     return layer
202     return None
203    
204     def OnSelChanged(self, event):
205 bh 14 if self.changing_selection:
206     # we're changing the selection ourselves (probably through
207     # self.normalize_selection(). ignore the event.
208     return
209 bh 6 self.normalize_selection()
210 bh 61 # SelectedLayer returns None if no layer is selected. Since
211     # passing None to interactor.SelectLayer deselects the layer we
212     # can simply pass the result of SelectedLayer on in all cases
213     self.app.interactor.SelectLayer(self.SelectedLayer())
214 bh 6
215     def layer_selected(self, layer):
216 bh 41 item = self.layer_to_item.get(id(layer))
217     if item is not None and item != self.GetSelection():
218     self.SelectItem(item)
219 bh 36
220    
221     class SessionTreeView(NonModalDialog):
222    
223     """Non modal dialog showing the session as a tree"""
224    
225     def __init__(self, parent, app, name):
226 jan 374 NonModalDialog.__init__(self, parent, app.interactor, name,
227     _("Session"))
228 bh 41 self.tree = SessionTreeCtrl(self, -1, app)
229 bh 36
230 jonathan 504 def OnClose(self, event):
231     NonModalDialog.OnClose(self, event)
232    
233 bh 151 # 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 jonathan 488

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26