/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/projlist.py
ViewVC logotype

Annotation of /branches/WIP-pyshapelib-bramz/Thuban/UI/projlist.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1933 - (hide annotations)
Tue Nov 11 16:37:53 2003 UTC (21 years, 3 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/projlist.py
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 bh 1850 # 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 bh 1933 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 bh 1850
36     When the selection changes the instance sends a
37     PROJ_SELECTION_CHANGED message.
38     """
39    
40 bh 1933 def __init__(self, parent, proj_files, orig_proj, ID = -1):
41 bh 1850 """Initialize the ProjectionList
42    
43     Parameters:
44    
45     parent -- The parent widget
46 bh 1933 proj_files -- a sequence of ProjFile objects
47 bh 1850 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 bh 1933 self.proj_files = proj_files
53     self._subscribe_proj_files()
54 bh 1850 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 bh 1933 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 bh 1853 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 bh 1850
84 bh 1933 def Destroy(self):
85     self._unsubscribe_proj_files()
86 bh 1853 # 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 bh 1850 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 bh 1933 for pf in self.proj_files:
114 bh 1850 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 bh 1853 # 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 bh 1850 for i in range(len(self.projections)):
183     p = self.projections[i][1]
184 bh 1853 self.SetItemState(i, p is proj and state or 0, state)
185 bh 1850
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 bh 1933 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 bh 1850 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