/[thuban]/trunk/thuban/Thuban/UI/projlist.py
ViewVC logotype

Contents of /trunk/thuban/Thuban/UI/projlist.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1850 - (show annotations)
Tue Oct 21 14:13:41 2003 UTC (21 years, 4 months ago) by bh
File MIME type: text/x-python
File size: 7495 byte(s)
New. The class ProjectionList is a
special wxListCtrl to show a list of projections in a more MVC
fashion

1 # Copyright (C) 2003 by Intevation GmbH
2 # Authors:
3 # Bernhard Herzog <[email protected]>
4 #
5 # This program is free software under the GPL (>=v2)
6 # Read the file COPYING coming with the software for details.
7
8 """List control for projections"""
9
10 __version__ = "$Revision$"
11 # $Source$
12 # $Id$
13
14 from wxPython.wx import *
15
16 from Thuban import _
17
18 from Thuban.Lib.connector import Publisher
19
20 from Thuban.Model.messages import PROJECTION_ADDED, PROJECTION_REMOVED, \
21 PROJECTION_REPLACED
22
23
24 PROJ_SELECTION_CHANGED = "PROJ_SELECTION_CHANGED"
25
26
27 class ProjectionList(wxListCtrl, Publisher):
28
29 """A ListCtrl that shows a list of projections
30
31 The list control is effectively a view on two ProjFile instances and
32 a specific 'original' projection (e.g. the projection of the current
33 map). The list control subscribes to the change messages of the
34 ProjFile instances to update the list whenever they change.
35
36 When the selection changes the instance sends a
37 PROJ_SELECTION_CHANGED message.
38 """
39
40 def __init__(self, parent, system_projs, user_projs, orig_proj, ID = -1):
41 """Initialize the ProjectionList
42
43 Parameters:
44
45 parent -- The parent widget
46 system_projs, user_projs -- the system and user ProjFiles
47 orig_proj -- The projection originally selected in the map/layer
48 """
49 wxListCtrl.__init__(self, parent, ID, style=wxLC_REPORT|wxLC_VIRTUAL)
50
51 self.InsertColumn(0, _("Available Projections"))
52 self.system_projs = system_projs
53 self.user_projs = user_projs
54 self.orig_proj = orig_proj
55 self.projections = []
56 self.proj_map = {}
57 self.needs_update = False
58 self.update_projections()
59 EVT_SIZE(self, self.OnSize)
60 EVT_LEFT_UP(self, self.mouse_left_up)
61 EVT_LIST_ITEM_SELECTED(self, self.GetId(), self.item_selected)
62 EVT_LIST_ITEM_DESELECTED(self, self.GetId(), self.item_deselected)
63 EVT_IDLE(self, self.OnIdle)
64 for pf in (self.system_projs, self.user_projs):
65 pf.Subscribe(PROJECTION_ADDED, self.pf_projection_added)
66 pf.Subscribe(PROJECTION_REMOVED, self.pf_projection_removed)
67 pf.Subscribe(PROJECTION_REPLACED, self.pf_projection_replaced)
68
69 def __del__(self):
70 wxListCtrl.__del__()
71 Publisher.__del__()
72
73 def Destroy(self):
74 wxListCtrl.Destroy()
75 Publisher.Destroy()
76
77 def update_on_idle(self):
78 self.needs_update = True
79
80 def OnIdle(self, evt):
81 if self.needs_update:
82 self.needs_update = False
83 self.update_projections()
84 evt.Skip()
85
86 def update_projections(self):
87 """Update the internal list of projection information"""
88
89 # Remember which projections are selected so that we can select
90 # them again after the update
91 selection = {}
92 for p in self.selected_projections():
93 selection[id(p[0])] = 1
94 old_length = len(self.projections)
95
96 # Build the new projection list
97 projections = [(_("<None>"), None, None)]
98 for pf in (self.user_projs, self.system_projs):
99 for p in pf.GetProjections():
100 projections.append((p.Label(), p, pf))
101 if self.orig_proj is not None:
102 projections.append((_("%s (current)") % self.orig_proj.Label(),
103 self.orig_proj, None))
104 self.projections = projections
105 self.projections.sort()
106
107 # Deselect all items with indices higher than the new length
108 # before settign the new item count This is a work-around for a
109 # bug in the listctrl which doesn't updat the selection count
110 # correctly in a call to SetItemCount if items have been
111 # selected with indices higher than the new count.
112 if len(self.projections) < old_length:
113 for i in xrange(len(self.projections), old_length):
114 self.SetItemState(i, 0, wxLIST_STATE_SELECTED)
115
116 self.SetItemCount(len(self.projections))
117
118 # Reselect the projections that had been selected before.
119 get = selection.get
120 count = 0
121 for i in xrange(len(self.projections)):
122 p = self.projections[i][1]
123 if get(id(p)):
124 state = wxLIST_STATE_SELECTED
125 count += 1
126 else:
127 state = 0
128 self.SetItemState(i, state, wxLIST_STATE_SELECTED)
129
130 # If the selection changed send a PROJ_SELECTION_CHANGED message
131 if count != len(selection):
132 self._issue_proj_selection_changed()
133
134 def pf_projection_added(self, proj):
135 """Subscribed to the projfile's PROJECTION_ADDED messages
136
137 Request an update the projection list in idle time.
138 """
139 self.update_on_idle()
140
141 def pf_projection_removed(self, proj):
142 """Subscribed to the projfile's PROJECTION_REMOVED messages
143
144 Request an update the projection list in idle time.
145 """
146 self.update_on_idle()
147
148 def pf_projection_replaced(self, old, new):
149 """Subscribed to the projfile's PROJECTION_REPLACED messages
150
151 Request an update the projection list in idle time.
152 """
153 self.update_on_idle()
154
155 def OnSize(self, evt):
156 self.SetColumnWidth(0, evt.GetSize().width)
157 evt.Skip()
158
159 def SelectProjection(self, proj):
160 """Select the projection and deselect all others."""
161 for i in range(len(self.projections)):
162 p = self.projections[i][1]
163 self.SetItemState(i, p is proj and wxLIST_STATE_SELECTED or 0,
164 wxLIST_STATE_SELECTED)
165
166 def ClearSelection(self):
167 """Deselect all projections."""
168 for i in range(len(self.projections)):
169 self.SetItemState(i, 0, wxLIST_STATE_SELECTED)
170
171 def OnGetItemText(self, item, col):
172 """Callback for the virtual ListCtrl mode"""
173 return self.projections[item][0]
174
175 def OnGetItemAttr(self, item):
176 """Callback for the virtual ListCtrl mode"""
177 return None
178
179 def OnGetItemImage(self, item):
180 """Callback for the virtual ListCtrl mode"""
181 return -1
182
183 def selected_projections(self):
184 """Return a list with all selected projection infos
185
186 The return value is a list of (proj, proj_file) pairs. proj_file
187 is the projection file object the projection was read from, if
188 any. Both proj and proj_file may be None, but if proj_file is
189 not None proj will also not be None.
190 """
191 return [self.projections[i][1:]
192 for i in range(len(self.projections))
193 if self.GetItemState(i, wxLIST_STATE_SELECTED)]
194
195 def _issue_proj_selection_changed(self):
196 """Internal: Issue a PROJ_SELECTION_CHANGED message"""
197 self.issue(PROJ_SELECTION_CHANGED, self.selected_projections())
198
199 def item_selected(self, evt):
200 """Handler for EVT_LIST_ITEM_SELECTED"""
201 self._issue_proj_selection_changed()
202
203 def item_deselected(self, evt):
204 #"""Handler for EVT_LIST_ITEM_DESELECTED"""
205 self._issue_proj_selection_changed()
206
207 def mouse_left_up(self, evt):
208 """Handle EVT_LEFT_UP events. Issue a selection message.
209
210 It's not clear whether the selection really has changed but the
211 selection events send by the list ctrl don't cover selecting
212 ranges of items :(.
213 """
214 self._issue_proj_selection_changed()

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26