/[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 1933 - (show annotations)
Tue Nov 11 16:37:53 2003 UTC (21 years, 3 months ago) by bh
File MIME type: text/x-python
File size: 8721 byte(s)
* Thuban/Model/resource.py (get_system_proj_file): Add a filename
parameter so that this function can be used for all proj files in
Resource/Projections
(DEFAULT_PROJ_FILE, EPSG_PROJ_FILE): New. Predefined filenames for
get_system_proj_file

* Thuban/UI/projdialog.py (ProjFrame.__init__): Instead of one
ProjFile self.__sysProjFile use a dictionary of system ProjFile
objects self._sys_proj_files
(ProjFrame.build_dialog): Adapt to the new changes in the
ProjectionList constructor. Add a check button to toggle whether
EPSG projections are shown
(ProjFrame._OnShowEPSG): New. Handler for the epsg check button
events.
(ProjFrame.load_user_proj, ProjFrame.load_system_proj): Only show
the busy cursor if the files have not yet been loaded by the
dialog.
(ProjFrame.load_system_proj): Add a parameter for the name of the
proj file. Maintain the dictionary of system projections
self._sys_proj_files

* Thuban/UI/projlist.py (ProjectionList): Merge the system_projs,
user_projs parameters into one parameter proj_files which is a
list of proj files.
(ProjectionList._subscribe_proj_files)
(ProjectionList._unsubscribe_proj_files): New. Move
subscription/unsubscription of projfile messages to separate
methods
(ProjectionList.Destroy): The unsubscribe is now done in
_unsubscribe_proj_files
(ProjectionList.update_projections): We now have a list of proj
file objects
(ProjectionList.SetProjFiles): New method to set a new list of
proj file objects

* test/test_proj.py (ProjFileReadTests.test_get_system_proj_file):
Specify explicitly which system proj file to load.

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 several ProjFile instances
32 and a specific 'original' projection (e.g. the projection of the
33 current map). The list control subscribes to the change messages of
34 the 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, proj_files, orig_proj, ID = -1):
41 """Initialize the ProjectionList
42
43 Parameters:
44
45 parent -- The parent widget
46 proj_files -- a sequence of ProjFile objects
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.proj_files = proj_files
53 self._subscribe_proj_files()
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
65 def __del__(self):
66 wxListCtrl.__del__()
67 Publisher.__del__()
68
69 def _subscribe_proj_files(self):
70 """Subscribe to the messages of self.proj_files"""
71 for pf in self.proj_files:
72 pf.Subscribe(PROJECTION_ADDED, self.pf_projection_added)
73 pf.Subscribe(PROJECTION_REMOVED, self.pf_projection_removed)
74 pf.Subscribe(PROJECTION_REPLACED, self.pf_projection_replaced)
75
76 def _unsubscribe_proj_files(self):
77 """Unsubscribe from the messages subscribed to in _subscribe_proj_files
78 """
79 for pf in self.proj_files:
80 pf.Unsubscribe(PROJECTION_ADDED, self.pf_projection_added)
81 pf.Unsubscribe(PROJECTION_REMOVED, self.pf_projection_removed)
82 pf.Unsubscribe(PROJECTION_REPLACED, self.pf_projection_replaced)
83
84 def Destroy(self):
85 self._unsubscribe_proj_files()
86 # Call wxListCtrl's method last because afterwards self is not
87 # an instance of ProjectionList anymore as wxPython replaces
88 # self.__class__ with its dead object class
89 Publisher.Destroy(self)
90 wxListCtrl.Destroy(self)
91
92 def update_on_idle(self):
93 self.needs_update = True
94
95 def OnIdle(self, evt):
96 if self.needs_update:
97 self.needs_update = False
98 self.update_projections()
99 evt.Skip()
100
101 def update_projections(self):
102 """Update the internal list of projection information"""
103
104 # Remember which projections are selected so that we can select
105 # them again after the update
106 selection = {}
107 for p in self.selected_projections():
108 selection[id(p[0])] = 1
109 old_length = len(self.projections)
110
111 # Build the new projection list
112 projections = [(_("<None>"), None, None)]
113 for pf in self.proj_files:
114 for p in pf.GetProjections():
115 projections.append((p.Label(), p, pf))
116 if self.orig_proj is not None:
117 projections.append((_("%s (current)") % self.orig_proj.Label(),
118 self.orig_proj, None))
119 self.projections = projections
120 self.projections.sort()
121
122 # Deselect all items with indices higher than the new length
123 # before settign the new item count This is a work-around for a
124 # bug in the listctrl which doesn't updat the selection count
125 # correctly in a call to SetItemCount if items have been
126 # selected with indices higher than the new count.
127 if len(self.projections) < old_length:
128 for i in xrange(len(self.projections), old_length):
129 self.SetItemState(i, 0, wxLIST_STATE_SELECTED)
130
131 self.SetItemCount(len(self.projections))
132
133 # Reselect the projections that had been selected before.
134 get = selection.get
135 count = 0
136 for i in xrange(len(self.projections)):
137 p = self.projections[i][1]
138 if get(id(p)):
139 state = wxLIST_STATE_SELECTED
140 count += 1
141 else:
142 state = 0
143 self.SetItemState(i, state, wxLIST_STATE_SELECTED)
144
145 # If the selection changed send a PROJ_SELECTION_CHANGED message
146 if count != len(selection):
147 self._issue_proj_selection_changed()
148
149 def pf_projection_added(self, proj):
150 """Subscribed to the projfile's PROJECTION_ADDED messages
151
152 Request an update the projection list in idle time.
153 """
154 self.update_on_idle()
155
156 def pf_projection_removed(self, proj):
157 """Subscribed to the projfile's PROJECTION_REMOVED messages
158
159 Request an update the projection list in idle time.
160 """
161 self.update_on_idle()
162
163 def pf_projection_replaced(self, old, new):
164 """Subscribed to the projfile's PROJECTION_REPLACED messages
165
166 Request an update the projection list in idle time.
167 """
168 self.update_on_idle()
169
170 def OnSize(self, evt):
171 self.SetColumnWidth(0, evt.GetSize().width)
172 evt.Skip()
173
174 def SelectProjection(self, proj):
175 """Select the projection and deselect all others."""
176 # Set both the wxLIST_STATE_SELECTED and wxLIST_STATE_FOCUSED
177 # flags on the newly selected item. If only
178 # wxLIST_STATE_SELECTED is set, some other item is focused and
179 # the first time the focus is moved with the keyboard the
180 # selection moves in unexpected ways.
181 state = wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED
182 for i in range(len(self.projections)):
183 p = self.projections[i][1]
184 self.SetItemState(i, p is proj and state or 0, state)
185
186 def ClearSelection(self):
187 """Deselect all projections."""
188 for i in range(len(self.projections)):
189 self.SetItemState(i, 0, wxLIST_STATE_SELECTED)
190
191 def SetProjFiles(self, proj_files):
192 """Set the projfile objects whose projections are shown in the list"""
193 self._unsubscribe_proj_files()
194 self.proj_files = proj_files
195 self._subscribe_proj_files()
196 self.update_projections()
197
198 def OnGetItemText(self, item, col):
199 """Callback for the virtual ListCtrl mode"""
200 return self.projections[item][0]
201
202 def OnGetItemAttr(self, item):
203 """Callback for the virtual ListCtrl mode"""
204 return None
205
206 def OnGetItemImage(self, item):
207 """Callback for the virtual ListCtrl mode"""
208 return -1
209
210 def selected_projections(self):
211 """Return a list with all selected projection infos
212
213 The return value is a list of (proj, proj_file) pairs. proj_file
214 is the projection file object the projection was read from, if
215 any. Both proj and proj_file may be None, but if proj_file is
216 not None proj will also not be None.
217 """
218 return [self.projections[i][1:]
219 for i in range(len(self.projections))
220 if self.GetItemState(i, wxLIST_STATE_SELECTED)]
221
222 def _issue_proj_selection_changed(self):
223 """Internal: Issue a PROJ_SELECTION_CHANGED message"""
224 self.issue(PROJ_SELECTION_CHANGED, self.selected_projections())
225
226 def item_selected(self, evt):
227 """Handler for EVT_LIST_ITEM_SELECTED"""
228 self._issue_proj_selection_changed()
229
230 def item_deselected(self, evt):
231 #"""Handler for EVT_LIST_ITEM_DESELECTED"""
232 self._issue_proj_selection_changed()
233
234 def mouse_left_up(self, evt):
235 """Handle EVT_LEFT_UP events. Issue a selection message.
236
237 It's not clear whether the selection really has changed but the
238 selection events send by the list ctrl don't cover selecting
239 ranges of items :(.
240 """
241 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