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

Diff of /branches/WIP-pyshapelib-bramz/Thuban/UI/legend.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 542 by jonathan, Thu Mar 20 09:43:16 2003 UTC revision 1241 by frank, Thu Jun 19 09:25:53 2003 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001, 2002, 2003 by Intevation GmbH  # Copyright (c) 2001, 2002, 2003 by Intevation GmbH
2  # Authors:  # Authors:
3  # Jonathan Coles <[email protected]>  # Jonathan Coles <[email protected]>
4    # Frank Koormann <[email protected]>
5  #  #
6  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
7  # Read the file COPYING coming with Thuban for details.  # Read the file COPYING coming with Thuban for details.
# Line 9  __version__ = "$Revision$" Line 10  __version__ = "$Revision$"
10    
11  from Thuban import _  from Thuban import _
12    
13    import resource
14    
15  from wxPython.wx import *  from wxPython.wx import *
 from dialogs import NonModalDialog  
16    
17  from Thuban.Model.layer import Layer  from Thuban.Model.layer import BaseLayer
18  from Thuban.Model.map import Map  from Thuban.Model.map import Map
19    from Thuban.Model.classification import ClassGroup
20    
21  from Thuban.Model.messages import *  from Thuban.Model.messages import \
22        MAP_STACKING_CHANGED, MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED, LAYER_CHANGED,\
23        LAYER_VISIBILITY_CHANGED, TITLE_CHANGED
24    
25  from Thuban.Model.classification import ClassGroup  from Thuban.UI.messages import SCALE_CHANGED
26    
27  from Thuban.UI.classifier import ClassDataPreviewer  from Thuban.UI.classifier import ClassDataPreviewer
28    from Thuban.UI.dock import DockPanel
29    from Thuban.UI.scalebar import ScaleBar
30    
31    from Thuban.Lib.connector import ConnectorError
32    
33  ID_LEGEND_MOVEUP = 4001  ID_LEGEND_TOP = 4001
34  ID_LEGEND_MOVEDOWN = 4002  ID_LEGEND_RAISE = 4002
35  ID_LEGEND_TREE = 4003  ID_LEGEND_LOWER = 4003
36  ID_LEGEND_CLASSIFY = 4004  ID_LEGEND_BOTTOM = 4004
37  ID_LEGEND_SHOWLAYER = 4005  ID_LEGEND_TREE = 4005
38  ID_LEGEND_HIDELAYER = 4006  ID_LEGEND_PROPS = 4006
39    ID_LEGEND_SHOWLAYER = 4007
40    ID_LEGEND_HIDELAYER = 4008
41    
42  BMP_SIZE_W = 30  BMP_SIZE_W = 15
43  BMP_SIZE_H = 15  BMP_SIZE_H = 15
44    
45  class Legend(NonModalDialog):  TOP_BMP = "top_layer"
46    RAISE_BMP = "raise_layer"
47    LOWER_BMP = "lower_layer"
48    BOTTOM_BMP = "bottom_layer"
49    SHOW_BMP  = "show_layer"
50    HIDE_BMP  = "hide_layer"
51    PROPS_BMP = "layer_properties"
52    
     def __init__(self, parent, name, map):  
         NonModalDialog.__init__(self, parent, name,  
                                 _("Legend: %s") % map.Title())  
53    
54          self.parent = parent  class LegendPanel(DockPanel):
55    
56        def __init__(self, parent, map, mainWindow):
57            DockPanel.__init__(self, parent, -1)
58    
59            self.mainWindow = mainWindow
60            self.parent = parent
61    
62          panel = wxPanel(self, -1)          self.buttons = []
63    
         topBox = wxBoxSizer(wxVERTICAL)  
64          panelBox = wxBoxSizer(wxVERTICAL)          panelBox = wxBoxSizer(wxVERTICAL)
65    
66          buttonBox = wxGridSizer(2, 3, 0, 0)          self.toolBar = wxToolBar(self, -1)
67            self.toolBar.SetToolBitmapSize(wxSize(24, 24))
68    
69          self.buttons = []          bmp = resource.GetBitmapResource(TOP_BMP, wxBITMAP_TYPE_XPM)
70            self.toolBar.AddTool(ID_LEGEND_TOP, bmp,
71                shortHelpString=_("Top Layer"))
72    
73            bmp = resource.GetBitmapResource(RAISE_BMP, wxBITMAP_TYPE_XPM)
74            self.toolBar.AddTool(ID_LEGEND_RAISE, bmp,
75                shortHelpString=_("Raise Layer"))
76    
77            bmp = resource.GetBitmapResource(LOWER_BMP, wxBITMAP_TYPE_XPM)
78            self.toolBar.AddTool(ID_LEGEND_LOWER, bmp,
79                shortHelpString=_("Lower Layer"))
80    
81            bmp = resource.GetBitmapResource(BOTTOM_BMP, wxBITMAP_TYPE_XPM)
82            self.toolBar.AddTool(ID_LEGEND_BOTTOM, bmp,
83                shortHelpString=_("Bottom Layer"))
84    
85            bmp = resource.GetBitmapResource(SHOW_BMP, wxBITMAP_TYPE_XPM)
86            self.toolBar.AddTool(ID_LEGEND_SHOWLAYER, bmp,
87                shortHelpString=_("Show Layer"))
88    
89            bmp = resource.GetBitmapResource(HIDE_BMP, wxBITMAP_TYPE_XPM)
90            self.toolBar.AddTool(ID_LEGEND_HIDELAYER, bmp,
91                shortHelpString=_("Hide Layer"))
92    
93            bmp = resource.GetBitmapResource(PROPS_BMP, wxBITMAP_TYPE_XPM)
94            self.toolBar.AddTool(ID_LEGEND_PROPS, bmp,
95                shortHelpString=_("Edit Layer Properties"))
96    
97            self.toolBar.Realize()
98            panelBox.Add(self.toolBar, 0, wxGROW, 0)
99    
100            EVT_TOOL(self, ID_LEGEND_TOP, self._OnMoveTop)
101            EVT_TOOL(self, ID_LEGEND_RAISE, self._OnMoveUp)
102            EVT_TOOL(self, ID_LEGEND_LOWER, self._OnMoveDown)
103            EVT_TOOL(self, ID_LEGEND_BOTTOM, self._OnMoveBottom)
104            EVT_TOOL(self, ID_LEGEND_PROPS, self._OnProperties)
105            EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)
106            EVT_TOOL(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)
107    
108          button = wxButton(self, ID_LEGEND_MOVEUP, _("Move Up"))          self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow)
         buttonBox.Add(button, 0, wxGROW | wxLEFT | wxRIGHT, 0)  
         self.buttons.append(button)  
109    
110          button = wxButton(self, ID_LEGEND_SHOWLAYER, _("Show Layer"))          panelBox.Add(self.tree, 1, wxGROW, 0)
         buttonBox.Add(button, 0, wxGROW | wxLEFT | wxRIGHT, 0)  
         self.buttons.append(button)  
111    
112          button = wxButton(self, ID_LEGEND_CLASSIFY, _("Classify"))          self.scalebarbitmap = ScaleBarBitmap(self, map, mainWindow)
113          buttonBox.Add(button, 0, wxGROW | wxLEFT | wxRIGHT, 0)          panelBox.Add(self.scalebarbitmap, 0, wxGROW, 0)
         self.buttons.append(button)  
114    
115          button = wxButton(self, ID_LEGEND_MOVEDOWN, _("Move Down"))          self.SetAutoLayout(True)
116          buttonBox.Add(button, 0, wxGROW | wxLEFT | wxRIGHT, 0)          self.SetSizer(panelBox)
117          self.buttons.append(button)          panelBox.SetSizeHints(self)
118    
         button = wxButton(self, ID_LEGEND_HIDELAYER, _("Hide Layer"))  
         buttonBox.Add(button, 0, wxGROW | wxLEFT | wxRIGHT, 0)  
         self.buttons.append(button)  
119    
120            self.panelBox = panelBox
121    
122          EVT_BUTTON(self, ID_LEGEND_MOVEUP, self._OnMoveUp)          self.__EnableButtons(False)
         EVT_BUTTON(self, ID_LEGEND_MOVEDOWN, self._OnMoveDown)  
         EVT_BUTTON(self, ID_LEGEND_CLASSIFY, self._OnClassify)  
         EVT_BUTTON(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)  
         EVT_BUTTON(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)  
123    
124          panelBox.Add(buttonBox, 0, 0, 4)          self.Create()
125    
126          self.tree = LegendTree(self, ID_LEGEND_TREE, map)          EVT_CLOSE(self, self._OnClose)
127    
         panelBox.Add(self.tree, 1, wxGROW, 4)  
128    
129          panel.SetAutoLayout(True)      def GetMap(self):
130          panel.SetSizer(panelBox)          return self.tree.GetMap()
         panelBox.SetSizeHints(panel)  
131    
132          topBox.Add(panel, 1, wxGROW, 0)      def SetMap(self, map):
133          panelBox.SetSizeHints(self)          self.tree.SetMap(map)
134            self.scalebarbitmap.SetCanvas(self.mainWindow.canvas)
135    
136          self.SetAutoLayout(True)      def DoOnSelChanged(self, layer, group):
137          self.SetSizer(topBox)  
138            ok = isinstance(layer, BaseLayer)
139            self.__EnableButtons(ok)
140    
141            self.mainWindow.SelectLayer(layer)
142    
143        def DoOnProperties(self):
144            list = self.tree.GetSelectedHierarchy()
145    
146            ok = isinstance(list[0], BaseLayer)
147            if ok:
148                self.mainWindow.OpenLayerProperties(list[0], list[1])
149    
150      def DoOnSelChanged(self):      def Destroy(self):
151          self.__EnableButtons(self.tree.GetSelection().IsOk())          self.__Close()
152    
153      def _OnClassify(self, event):      def _OnProperties(self, event):
154          self.tree.DoOnClassify()          self.DoOnProperties()
155    
156        def _OnMoveTop(self, event):
157            self.tree.MoveCurrentItemTop()
158            
159      def _OnMoveUp(self, event):      def _OnMoveUp(self, event):
160          self.tree.MoveCurrentItemUp()          self.tree.MoveCurrentItemUp()
161    
162      def _OnMoveDown(self, event):      def _OnMoveDown(self, event):
163          self.tree.MoveCurrentItemDown()          self.tree.MoveCurrentItemDown()
164    
165        def _OnMoveBottom(self, event):
166            self.tree.MoveCurrentItemBottom()
167    
168      def _OnShowLayer(self, event):      def _OnShowLayer(self, event):
169          self.tree.DoOnShowLayer()          self.tree.DoOnShowLayer()
170          pass          pass
171    
172        #def Close(self, force = False):
173            #DockPanel.Close(self, force)
174            
175        def _OnClose(self, event):
176            self.__Close()
177    
178      def _OnHideLayer(self, event):      def _OnHideLayer(self, event):
179          self.tree.DoOnHideLayer()          self.tree.DoOnHideLayer()
180          pass          pass
181    
   
182      def __EnableButtons(self, on):      def __EnableButtons(self, on):
183          for b in self.buttons:          self.toolBar.EnableTool(ID_LEGEND_TOP, on)
184              b.Enable(on)          self.toolBar.EnableTool(ID_LEGEND_RAISE, on)
185            self.toolBar.EnableTool(ID_LEGEND_LOWER, on)
186            self.toolBar.EnableTool(ID_LEGEND_BOTTOM, on)
187            self.toolBar.EnableTool(ID_LEGEND_SHOWLAYER,  on)
188            self.toolBar.EnableTool(ID_LEGEND_HIDELAYER,  on)
189            self.toolBar.EnableTool(ID_LEGEND_PROPS, on)
190    
191        def __Close(self):
192            self.tree.Close()
193    
194  class LegendTree(wxTreeCtrl):  class LegendTree(wxTreeCtrl):
195    
196      def __init__(self, parent, id, map):      def __init__(self, parent, id, map, mainWindow):
197          wxTreeCtrl.__init__(self, parent, id,          wxTreeCtrl.__init__(self, parent, id,
198                              style = wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT,                              style = wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT,
199                              size = (200, 200))                              size = (200, 200))
200    
201            self.mainWindow = mainWindow
202            self.map = None
203          self.parent = parent          self.parent = parent
204          self.map = map          self.changing_selection = 0
         self.layer2id = None  
205    
206            #
207            # The image list used by the wxTreeCtrl causes problems when
208            # we remove layers and/or change a classification because it
209            # changes the image indices if you remove images from the list.
210            # Rather than removing unused images we use this list to keep
211            # track of which indices are available in the image list
212            # (because of a previous removal) and then  replace those indices
213            # with new images rather than appending to the end of the image
214            # list (assuming there are any that are available).
215            #
216            self.availImgListIndices = []
217    
218          self.image_list = None          self.image_list = None
219          self.emptyImageIndex = 0          self.emptyImageIndex = 0
220    
221          self.previewer = ClassDataPreviewer()          self.previewer = ClassDataPreviewer()
222    
223            self.preventExpandCollapse = False
224            self.raiseProperties = False
225    
226          EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)          EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)
227          EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)          EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)
228            EVT_TREE_ITEM_EXPANDING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
229            EVT_TREE_ITEM_COLLAPSING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
230    
231          map.Subscribe(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged)          EVT_CLOSE(self, self._OnClose)
         map.Subscribe(MAP_LAYERS_CHANGED, self._OnMsgMapLayersChanged)  
   
         self.__FillTree(map)  
232    
233      def MoveCurrentItemUp(self):          self.SetMap(map)
         cur_id = self.GetSelection()  
         assert(cur_id.IsOk())  
234    
235          cur_data = self.GetPyData(cur_id)      def find_layer(self, layer):
236            """Return the tree item for the layer"""
237            root = self.GetRootItem()
238            id, cookie = self.GetFirstChild(root, 0)
239            while id.IsOk():
240                if self.GetPyData(id) is layer:
241                    return id
242                id, cookie = self.GetNextChild(root, cookie)
243            return None
244    
245        def _OnClose(self, event):
246            self.SetMap(None)
247    
248        def GetMap(self):
249            return self.map
250    
251        def SetMap(self, map):
252    
253            sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),
254                        (MAP_LAYERS_ADDED, self._OnMsgMapLayersAdded),
255                        (MAP_LAYERS_REMOVED, self._OnMsgMapLayersRemoved)]
256    
257            if self.map is not None:
258                for msg, func in sub_list: self.map.Unsubscribe(msg, func)
259                #self.mainWindow.application.Unsubscribe(SESSION_REPLACED,
260                    #self._OnMsgMapsChanged)
261                #try:
262                    #self.mainWindow.application.session.Unsubscribe(MAPS_CHANGED,
263                        #self._OnMsgMapsChanged)
264                #except ConnectorError:
265                    #pass
266                self.DeleteAllItems()
267            
268            self.map = map
269    
270          #prev_id = self.GetPrevSibling(cur_id)          if self.map is not None:
271                for msg, func in sub_list: self.map.Subscribe(msg, func)
272                #self.mainWindow.application.session.Subscribe(MAPS_CHANGED,
273                    #self._OnMsgMapsChanged)
274                #self.mainWindow.application.Subscribe(SESSION_REPLACED,
275                    #self._OnMsgMapsChanged)
276                self.__FillTree(self.map)
277    
278          #      def MoveCurrentItemTop(self):
279          # Get out if there's nowhere to go          layer, group = self.GetSelectedHierarchy()
         #  
         #if prev_id == INVALID_TREE_ID: return  
280    
281          if isinstance(cur_data, Layer):          if layer is not None:
282              self.map.RaiseLayer(cur_data)              self.map.MoveLayerToTop(layer)
283          elif isinstance(cur_data, ClassGroup):          else:
284                assert False, "Shouldn't be allowed."
285              pass              pass
286    
287        def MoveCurrentItemUp(self):
288            layer, group = self.GetSelectedHierarchy()
289    
290            if layer is not None:
291                self.map.RaiseLayer(layer)
292          else:          else:
293              assert(False, "Shouldn't be here.")              assert False, "Shouldn't be allowed."
294              pass              pass
295    
296      def MoveCurrentItemDown(self):      def MoveCurrentItemDown(self):
297          cur_id = self.GetSelection()          layer, group = self.GetSelectedHierarchy()
         assert(cur_id.IsOk())  
   
         cur_data = self.GetPyData(cur_id)  
298    
299          if isinstance(cur_data, Layer):          if layer is not None:
300              self.map.LowerLayer(cur_data)              self.map.LowerLayer(layer)
         elif isinstance(cur_data, ClassGroup):  
             pass  
301          else:          else:
302              assert(False, "Shouldn't be here.")              assert False, "Shouldn't be allowed."
303              pass              pass
304    
305        def MoveCurrentItemBottom(self):
306            layer, group = self.GetSelectedHierarchy()
307    
308            if layer is not None:
309                self.map.MoveLayerToBottom(layer)
310            else:
311                assert False, "Shouldn't be allowed."
312                pass
313    
314      def OnCompareItems(self, item1, item2):      def OnCompareItems(self, item1, item2):
315    
316          data1 = self.GetPyData(item1)          data1 = self.GetPyData(item1)
317          data2 = self.GetPyData(item2)          data2 = self.GetPyData(item2)
318    
319          if isinstance(data1, Layer):          if isinstance(data1, BaseLayer):
320              layers = self.map.Layers()              layers = self.map.Layers()
321              return layers.index(data2) - layers.index(data1)              return layers.index(data2) - layers.index(data1)
322          else:          else:
323              return wxTreeCtrl.OnCompareItems(self, item1, item2)              return wxTreeCtrl.OnCompareItems(self, item1, item2)
324    
   
325      def DoOnShowLayer(self):      def DoOnShowLayer(self):
326          self.__ShowHideLayer(True)          layer, group = self.GetSelectedHierarchy()
327            layer.SetVisible(True)
328    
329      def DoOnHideLayer(self):      def DoOnHideLayer(self):
330          self.__ShowHideLayer(False)          layer, group = self.GetSelectedHierarchy()
331            layer.SetVisible(False)
332    
333      def DoOnClassify(self):      def Sort(self):
334          id = self.GetSelection()          self.SortChildren(self.GetRootItem())
         assert(id.IsOk())  
335    
336          item = self.GetPyData(id)      def GetSelectedHierarchy(self):
337          if isinstance(item, ClassGroup):          id = self.GetSelection()
             id = self.GetItemParent(id)  
             assert(id.IsOk())  
             item = self.GetPyData(id)  
338    
339          self.parent.parent.OpenClassifier(item)          if not id.IsOk():
340                return (None, None)
341    
342      def Sort(self):          layer = self.GetPyData(id)
343          self.SortChildren(self.GetRootItem())          group = None
344    
345            if isinstance(layer, ClassGroup):
346                id = self.GetItemParent(id)
347                assert id.IsOk()
348                group = layer
349                layer = self.GetPyData(id)
350    
351            return (layer, group)
352    
353        def _OnMsgMapsChanged(self):
354            #print self.map is self.mainWindow.Map()
355            self.SetMap(self.mainWindow.Map())
356            
357      def _OnSelChanged(self, event):      def _OnSelChanged(self, event):
358          self.parent.DoOnSelChanged()          # If we change the selection from normalize_selection do nothing.
359            if self.changing_selection:
360                return
361    
362            self.normalize_selection()
363            self.__UpdateSelection()
364    
365        def normalize_selection(self):
366            """Select the layer containing currently selected item"""
367            # This is really a workaround for a bug in wx where deleting a
368            # subtree with DeleteChildren does not update the selection
369            # properly and can lead to segfaults later because the return
370            # value of GetSelection points to invalid data.
371            item = self.GetSelection()
372            while item.IsOk():
373                object = self.GetPyData(item)
374                if isinstance(object, BaseLayer):
375                    break
376                item = self.GetItemParent(item)
377            else:
378                # No layer was found in the chain of parents, so there's
379                # nothing we can do.
380                return
381    
382            self.changing_selection = 1
383            try:
384                self.SelectItem(item)
385            finally:
386                self.changing_selection = 0
387    
388    
389        def OnItemExpandCollapse(self, event):
390            if self.preventExpandCollapse:
391                event.Veto()
392                self.preventExpandCollapse = False
393    
394      def _OnItemActivated(self, event):      def _OnItemActivated(self, event):
395          self.DoOnClassify()          # The following looks strange but is need under Windows to
396            # raise the Properties on double-click: The tree control
397            # always gets an Expanded / Collapsed event after the ItemActivated
398            # on double click, which raises the main window again. We add a second
399            # ItemActivated event to the queue, which simply raises the already
400            # displayed window.
401            if self.raiseProperties:
402                self.parent.DoOnProperties()
403                self.raiseProperties = False
404            else:
405                self.raiseProperties = True
406                self.preventExpandCollapse = True
407                self.parent.DoOnProperties()
408                self.AddPendingEvent(event)
409    
410      def _OnMsgLayerChanged(self, layer):      def _OnMsgLayerChanged(self, layer):
411          assert(isinstance(layer, Layer))          assert isinstance(layer, BaseLayer)
412    
413          id = self.layer2id[layer]          id = self.find_layer(layer)
414            assert id is not None
415    
416          self.__FillTreeLayer(id)          self.__FillTreeLayer(id)
417            self.__UpdateSelection()
418    
419      def _OnMsgMapStackingChanged(self, *args):      def _OnMsgMapStackingChanged(self, *args):
420          self.Sort()          self.Sort()
421            id = self.GetSelection()
422    
423      def _OnMsgMapLayersChanged(self, map):          if id.IsOk():
424          assert(id(map) == id(self.map))              self.EnsureVisible(id)
425            self.__UpdateSelection()
426    
427          self.__FillTree(self.map)      def _OnMsgMapLayersAdded(self, map):
428            assert map is self.map
429    
430      def __FillTree(self, map):          # Build a dict with all layers known by the the tree as keys
431            layers = {}
432            root = self.GetRootItem()
433            id, cookie = self.GetFirstChild(root, 0)
434            while id.IsOk():
435                layers[self.GetPyData(id)] = 1
436                id, cookie = self.GetNextChild(root, cookie)
437    
438          assert(isinstance(map, Map))          # Add layers in the map but not in the dict
439            i = 0
440            for l in map.Layers():
441                if not l in layers:
442                    self.__AddLayer(i, l)
443    
444          self.Freeze()          self.__UpdateSelection()
445    
446          self.__DeleteAllItems()      def _OnMsgMapLayersRemoved(self, map):
447            assert map is self.map
448    
449          if map.HasLayers():          layers = map.Layers()
450    
451              self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)          root = self.GetRootItem()
452                                                                                            id, cookie = self.GetFirstChild(root, 0)
453              bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)          while id.IsOk():
454              dc = wxMemoryDC()              if self.GetPyData(id) not in layers:
455              dc.SelectObject(bmp)                  self.__RemoveLayer(id)
456              dc.SetBrush(wxBLACK_BRUSH)              id, cookie = self.GetNextChild(root, cookie)
             dc.Clear()  
             dc.SelectObject(wxNullBitmap)  
                                                                                   
             self.emptyImageIndex = \  
                 self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))  
                                                                                   
             self.AssignImageList(self.image_list)  
457    
             root = self.AddRoot("")  
458    
459              for l in map.Layers():          self.__UpdateSelection()
460                  id = self.PrependItem(root, l.Title())  
461                  l.Subscribe(LAYER_CHANGED, self._OnMsgLayerChanged)      def _OnMsgLayerVisibilityChanged(self, layer):
462                  self.SetPyData(id, l)          assert isinstance(layer, BaseLayer)
463                  font = self.GetItemFont(id)  
464                  if not l.Visible():          self.__ShowHideLayer(layer)
465                      font.SetStyle(wxITALIC)          self.__UpdateSelection()
466                      self.SetItemFont(id, font)  
467        def _OnMsgLayerTitleChanged(self, layer):
468    
469            id = self.find_layer(layer)
470            if id.IsOk():
471                self.SetItemText(id, layer.Title())
472            self.__UpdateSelection()
473    
474        def __UpdateSelection(self):
475            layer, group = self.GetSelectedHierarchy()
476            self.parent.DoOnSelChanged(layer, group)
477            
478        def __FillTree(self, map):
479    
480            self.Freeze()
481    
482                  self.layer2id[l] = id          self.DeleteAllItems()
483    
484                  self.__FillTreeLayer(id)          if map.HasLayers():
485                  self.Expand(id)              root = self.GetRootItem()
486                for l in map.Layers():
487                    self.__AddLayer(0, l)
488    
489          self.Thaw()          self.Thaw()
490    
# Line 283  class LegendTree(wxTreeCtrl): Line 495  class LegendTree(wxTreeCtrl):
495    
496          self.DeleteChildren(pid)          self.DeleteChildren(pid)
497    
498          clazz = layer.GetClassification()          if layer.HasClassification():
   
         shapeType = layer.ShapeType()  
499    
500          for g in clazz:              clazz = layer.GetClassification()
             id = self.AppendItem(pid, g.GetDisplayText())  
             self.SetPyData(id, g)  
501    
502              bmp = self.__BuildGroupImage(g, shapeType)              shapeType = layer.ShapeType()
503    
504              if bmp is None:              show = layer.Visible()
505                  self.SetItemImage(id, self.emptyImageIndex)              for g in clazz:
506              else:                  if g.IsVisible():
507                  i = self.image_list.Add(bmp)                      id = self.AppendItem(pid, g.GetDisplayText())
508                  self.SetItemImage(id, i)                      self.SetPyData(id, g)
509                        self.__SetVisibilityStyle(show, id)
510    
511                        bmp = self.__BuildGroupImage(g, shapeType)
512    
513                        if bmp is None:
514                            self.SetItemImage(id, -1)
515                            self.SetItemSelectedImage(id, -1)
516                        else:
517                            if self.availImgListIndices:
518                                i = self.availImgListIndices.pop(0)
519                                self.image_list.Replace(i, bmp)
520                            else:
521                                i = self.image_list.Add(bmp)
522    
523              #self.layer2id[g] = id                          self.SetItemImage(id, i)
524                            self.SetItemSelectedImage(id, i)
525    
526          self.Thaw()          self.Thaw()
527    
528      def __BuildGroupImage(self, group, shapeType):      def __BuildGroupImage(self, group, shapeType):
         assert(isinstance(group, ClassGroup))  
529    
530          bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)          bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
531          #brush = wxBrush(Color2wxColour(item[1]), wxSOLID)          #brush = wxBrush(Color2wxColour(item[1]), wxSOLID)
# Line 316  class LegendTree(wxTreeCtrl): Line 537  class LegendTree(wxTreeCtrl):
537    
538          return bmp          return bmp
539    
540      def __DeleteAllItems(self):      def DeleteAllItems(self):
         self.DeleteAllItems()  
         self.layer2id = {}  
541    
542            pid = self.GetRootItem()
543    
544      def __ShowHideLayer(self, show):          id, cookie = self.GetFirstChild(pid, 123)
545          id = self.GetSelection()          while id.IsOk():
546          assert(id.IsOk())              self.__RemoveLayer(id)
547                id, cookie = self.GetNextChild(pid, cookie)
548    
549            wxTreeCtrl.DeleteAllItems(self)
550    
551        def __AddLayer(self, before, l):
552            root = self.GetRootItem()
553            id = self.InsertItemBefore(root, before,
554                                l.Title(),
555                                self.mapImageIndex,
556                                self.mapImageIndex)
557    
558            self.SetPyData(id, l)
559            self.__SetVisibilityStyle(l.Visible(), id)
560    
561            self.__FillTreeLayer(id)
562            self.Expand(id)
563    
564            l.Subscribe(LAYER_CHANGED, self._OnMsgLayerChanged)
565            l.Subscribe(LAYER_VISIBILITY_CHANGED,
566                        self._OnMsgLayerVisibilityChanged)
567            l.Subscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
568    
569        def __RemoveLayer(self, id):
570            self.DeleteChildren(id)
571    
572            layer = self.GetPyData(id)
573            layer.Unsubscribe(LAYER_CHANGED,
574                              self._OnMsgLayerChanged)
575            layer.Unsubscribe(LAYER_VISIBILITY_CHANGED,
576                              self._OnMsgLayerVisibilityChanged)
577            layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
578    
579            self.Delete(id)
580    
581        def DeleteChildren(self, pid):
582            id, cookie = self.GetFirstChild(pid, 123)
583            while id.IsOk():
584                self.availImgListIndices.append(self.GetItemImage(id))
585                id, cookie = self.GetNextChild(pid, cookie)
586            wxTreeCtrl.DeleteChildren(self, pid)
587    
588        def GetRootItem(self):
589            root = wxTreeCtrl.GetRootItem(self)
590    
591            if not root.IsOk():
592                self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)
593    
594                bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
595                dc = wxMemoryDC()
596                dc.SelectObject(bmp)
597                dc.SetBrush(wxBLACK_BRUSH)
598                dc.Clear()
599                dc.SelectObject(wxNullBitmap)
600    
601                self.emptyImageIndex = \
602                    self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
603    
604                bmp = resource.GetBitmapResource("legend_icon_layer",
605                                                  wxBITMAP_TYPE_XPM)
606                self.mapImageIndex = \
607                    self.image_list.Add(bmp)
608    
609                self.AssignImageList(self.image_list)
610                self.availImgListIndices = []
611    
612                root = self.AddRoot("")
613    
614            return root
615    
616        def __SetVisibilityStyle(self, visible, id):
617            font = self.GetItemFont(id)
618    
619            if visible:
620                font.SetStyle(wxNORMAL)
621                color = wxBLACK
622            else:
623                #font.SetStyle(wxITALIC)
624                font.SetStyle(wxNORMAL)
625                color = wxLIGHT_GREY
626    
627            self.SetItemTextColour(id, color)
628            self.SetItemFont(id, font)
629                    
630          item = self.GetPyData(id)      def __ShowHideLayer(self, layer):
631          if isinstance(item, ClassGroup):          parent = self.find_layer(layer)
632              id = self.GetItemParent(id)          assert parent.IsOk()
633              assert(id.IsOk())  
634              item = self.GetPyData(id)          visible = layer.Visible()
635    
636            self.__SetVisibilityStyle(visible, parent)
637    
638            id, cookie = self.GetFirstChild(parent, 123)
639    
640          if show != item.Visible():          while id.IsOk():
641                self.__SetVisibilityStyle(visible, id)
642                id, cookie = self.GetNextChild(parent, cookie)
643                
644    class ScaleBarBitmap(wxBoxSizer):
645    
646        def __init__(self, parent, map, mainWindow):
647            # While the width is fixed, get the height _now_.
648            dc = wxMemoryDC()
649            textwidth, textheight = dc.GetTextExtent("%d"%0)
650            self.width = 210
651            self.height = textheight + 3*2 + 8
652    
653            wxBoxSizer.__init__(self, wxVERTICAL)
654            bmp=wxEmptyBitmap(self.width, self.height)
655            self.scalebarBitmap = wxStaticBitmap(parent, -1, bmp)
656            self.Add(self.scalebarBitmap, 0, wxALIGN_CENTER|wxLEFT|wxTOP|wxRIGHT, 1)
657    
658            self.mainWindow = mainWindow
659            self.parent = parent
660            self.canvas = None
661            self.SetCanvas(self.mainWindow.canvas)
662    
663              item.SetVisible(show)      def SetCanvas(self, canvas):
664            sub_list = [(SCALE_CHANGED, self._OnMsgScaleChanged)]
665    
666              font = self.GetItemFont(id)          if self.canvas is not None:
667              if show:              for msg, func in sub_list: self.canvas.Unsubscribe(msg, func)
668                  font.SetStyle(wxNORMAL)          
669                  self.SetItemFont(id, font)          self.canvas = canvas
670              else:          self.scalebar = ScaleBar(canvas.map)
671                  font.SetStyle(wxITALIC)  
672                  self.SetItemFont(id, font)          if self.canvas is not None:
673                for msg, func in sub_list: self.canvas.Subscribe(msg, func)
674                self.__SetScale(self.canvas.scale)
675    
676        def _OnMsgScaleChanged(self, scale):
677            self.__SetScale(scale)
678    
679        def __SetScale(self, scale):
680            bmp = wxEmptyBitmap(self.width, self.height)
681            dc = wxMemoryDC()
682            dc.SelectObject(bmp)
683            dc.Clear()
684    
685            if self.canvas.map is not None \
686                and self.canvas.map.projection is not None:
687                self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())
688    
689            self.scalebarBitmap.SetBitmap(bmp)
690    

Legend:
Removed from v.542  
changed lines
  Added in v.1241

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26