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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2878 - (hide annotations)
Tue Jun 2 11:06:15 2009 UTC (15 years, 9 months ago) by dpinte
File MIME type: text/x-python
File size: 8738 byte(s)
2009-06-02 Didrik Pinte <dpinte@dipole-consulting.com>

  * Thuban/UI/projlist.py : removed called to inexistant __del__ method on
                            wx.ListCtrl


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