/[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 488 - (hide annotations)
Fri Mar 7 18:21:25 2003 UTC (22 years ago) by jonathan
Original Path: trunk/thuban/Thuban/UI/tree.py
File MIME type: text/x-python
File size: 8192 byte(s)
(SessionTreeView): Remove OnClose and let
        the parent class handle it. Add Shutdown() to unsubscibe from
        event notification and call the parent Shutdown(). This was
        necessary so the application can close the tree window.

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 bh 6 from messages import SESSION_CHANGED, SELECTED_LAYER
27    
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 bh 6 self.app.Subscribe(SESSION_CHANGED, self.session_changed)
66     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 self.image_list = wxImageList(BMP_SIZE, BMP_SIZE)
72     self.AssignImageList(self.image_list)
73    
74 bh 6 # pretend the session has changed to build the initial tree
75     self.session_changed()
76    
77 bh 36 EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
78 bh 6
79 bh 151 def unsubscribe_all(self):
80     if self.session is not None:
81 bh 233 self.session.Unsubscribe(CHANGED, self.update_tree)
82 bh 161 self.session = None
83 bh 151 self.app.Unsubscribe(SESSION_CHANGED, self.session_changed)
84     self.app.interactor.Unsubscribe(SELECTED_LAYER, self.layer_selected)
85    
86 bh 6 def update_tree(self, *args):
87     """Clear and rebuild the tree"""
88 bh 36 self.DeleteAllItems()
89 bh 41 self.layer_to_item.clear()
90 jan 104
91 bh 217 session = self.app.session
92     info = session.TreeInfo()
93     root = self.AddRoot(info[0])
94     self.add_items(root, info[1])
95 bh 36 self.Expand(root)
96 bh 217 # select the selected layer
97     selected_layer = self.app.interactor.selected_layer
98     if selected_layer is not None:
99 bh 218 # One would expect that the selected_layer's id is in
100     # layer_to_item at this point as we've just rebuilt that
101     # mapping completely. However, when a new session is loaded
102     # for instance, it can happen that the tree view is updated
103     # before the interactor in which case selected_layer may be
104     # a layer of the old session.
105     item = self.layer_to_item.get(id(selected_layer))
106     if item is not None:
107     self.SelectItem(item)
108 bh 6
109 bh 217 def add_items(self, parent, items):
110 jonathan 383
111     if items is None: return
112    
113 bh 217 for item in items:
114     if hasattr(item, "TreeInfo"):
115     # Supports the TreeInfo protocol
116     info = item.TreeInfo()
117     treeitem = self.AppendItem(parent, info[0])
118     self.SetPyData(treeitem, item)
119     self.add_items(treeitem, info[1])
120     self.Expand(treeitem)
121     if isinstance(item, Layer):
122     self.layer_to_item[id(item)] = treeitem
123 jonathan 383 elif isinstance(item, StringType) or \
124     isinstance(item, UnicodeType):
125 bh 217 # it's a string
126     self.AppendItem(parent, item)
127     else:
128     # assume its a sequence (title, items)
129 jonathan 383 if isinstance(item[1], Color):
130    
131 jonathan 417 treeitem = self.AppendItem(parent, "(%s)" % item[0])
132    
133 jonathan 383 bmp = wxEmptyBitmap(BMP_SIZE, BMP_SIZE)
134 jonathan 443 brush = wxBrush(Color2wxColour(item[1]), wxSOLID)
135 jonathan 383 dc = wxMemoryDC()
136     dc.SelectObject(bmp)
137     dc.SetBrush(brush)
138     dc.Clear()
139     dc.DrawRoundedRectangle(0, 0,
140     bmp.GetWidth(), bmp.GetHeight(),
141     4)
142     dc.SelectObject(wxNullBitmap)
143    
144     i = self.image_list.Add(bmp)
145     self.SetItemImage(treeitem, i)
146     else:
147     treeitem = self.AppendItem(parent, item[0])
148     self.add_items(treeitem, item[1])
149 bh 217 self.Expand(treeitem)
150 jan 198
151 bh 6 def session_changed(self, *args):
152 bh 151 new_session = self.app.session
153     # if the session has changed subscribe/unsubscribe
154     if self.session is not new_session:
155     if self.session is not None:
156 bh 233 self.session.Unsubscribe(CHANGED, self.update_tree)
157 bh 151 if new_session is not None:
158 bh 233 new_session.Subscribe(CHANGED, self.update_tree)
159 bh 151 self.session = new_session
160 bh 6 self.update_tree()
161    
162     def normalize_selection(self):
163     """Select the layer or map containing currently selected item"""
164 bh 36 item = self.GetSelection()
165 bh 6 while item.IsOk():
166 bh 36 object = self.GetPyData(item)
167 bh 6 if isinstance(object, Layer) or isinstance(object, Map):
168     break
169 bh 36 item = self.GetItemParent(item)
170 bh 353 else:
171     # No layer or map was found in the chain of parents, so
172     # there's nothing we can do.
173     return
174 bh 6
175 bh 14 self.changing_selection = 1
176     try:
177 bh 36 self.SelectItem(item)
178 bh 14 finally:
179     self.changing_selection = 0
180 bh 6
181     def SelectedLayer(self):
182     """Return the layer object currently selected in the tree.
183     Return None if no layer is selected"""
184 bh 36 layer = self.GetPyData(self.GetSelection())
185 bh 6 if isinstance(layer, Layer):
186     return layer
187     return None
188    
189     def OnSelChanged(self, event):
190 bh 14 if self.changing_selection:
191     # we're changing the selection ourselves (probably through
192     # self.normalize_selection(). ignore the event.
193     return
194 bh 6 self.normalize_selection()
195 bh 61 # SelectedLayer returns None if no layer is selected. Since
196     # passing None to interactor.SelectLayer deselects the layer we
197     # can simply pass the result of SelectedLayer on in all cases
198     self.app.interactor.SelectLayer(self.SelectedLayer())
199 bh 6
200     def layer_selected(self, layer):
201 bh 41 item = self.layer_to_item.get(id(layer))
202     if item is not None and item != self.GetSelection():
203     self.SelectItem(item)
204 bh 36
205    
206     class SessionTreeView(NonModalDialog):
207    
208     """Non modal dialog showing the session as a tree"""
209    
210     def __init__(self, parent, app, name):
211 jan 374 NonModalDialog.__init__(self, parent, app.interactor, name,
212     _("Session"))
213 bh 41 self.tree = SessionTreeCtrl(self, -1, app)
214 bh 36
215 jonathan 488 def Shutdown(self):
216 bh 151 # if there were a way to get notified when the tree control
217     # itself is destroyed we could use that to unsubscribe instead
218     # of doing it here. (EVT_WINDOW_DESTROY doesn't seem to sent at
219     # all)
220     self.tree.unsubscribe_all()
221 jonathan 488
222     # this needs to come last because Destroy will be called
223     NonModalDialog.Shutdown(self)
224    

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26