/[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 1058 - (hide annotations)
Tue May 27 11:30:29 2003 UTC (21 years, 9 months ago) by frank
Original Path: trunk/thuban/Thuban/UI/tree.py
File MIME type: text/x-python
File size: 8821 byte(s)
Dialog derived from NonModalNonParentDialog

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