/[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 639 by jonathan, Thu Apr 10 14:35:39 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 *
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
 from Thuban.Model.messages import *  
19  from Thuban.Model.classification import ClassGroup  from Thuban.Model.classification import ClassGroup
20    
21  from Thuban.UI.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.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  from Thuban.UI.dock import DockPanel
29    from Thuban.UI.scalebar import ScaleBar
30    
31  from Thuban.Lib.connector import ConnectorError  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_PROPS = 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    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    
53    
54  class LegendPanel(DockPanel):  class LegendPanel(DockPanel):
55    
56      def __init__(self, parent, map, mainWindow):      def __init__(self, parent, map, mainWindow):
# Line 40  class LegendPanel(DockPanel): Line 59  class LegendPanel(DockPanel):
59          self.mainWindow = mainWindow          self.mainWindow = mainWindow
60          self.parent = parent          self.parent = parent
61    
         panelBox = wxBoxSizer(wxVERTICAL)  
   
         buttonBox = wxGridSizer(2, 3, 0, 0)  
   
62          self.buttons = []          self.buttons = []
63    
64          button = wxButton(self, ID_LEGEND_MOVEUP, _("Move Up"))          panelBox = wxBoxSizer(wxVERTICAL)
65          buttonBox.Add(button, 0, wxGROW | wxLEFT | wxRIGHT, 0)  
66          self.buttons.append(button)          self.toolBar = wxToolBar(self, -1)
67            self.toolBar.SetToolBitmapSize(wxSize(24, 24))
         button = wxButton(self, ID_LEGEND_SHOWLAYER, _("Show Layer"))  
         buttonBox.Add(button, 0, wxGROW | wxLEFT | wxRIGHT, 0)  
         self.buttons.append(button)  
   
         button = wxButton(self, ID_LEGEND_PROPS, _("Properties"))  
         buttonBox.Add(button, 0, wxGROW | wxLEFT | wxRIGHT, 0)  
         self.buttons.append(button)  
   
         button = wxButton(self, ID_LEGEND_MOVEDOWN, _("Move Down"))  
         buttonBox.Add(button, 0, wxGROW | wxLEFT | wxRIGHT, 0)  
         self.buttons.append(button)  
   
         button = wxButton(self, ID_LEGEND_HIDELAYER, _("Hide Layer"))  
         buttonBox.Add(button, 0, wxGROW | wxLEFT | wxRIGHT, 0)  
         self.buttons.append(button)  
   
         EVT_BUTTON(self, ID_LEGEND_MOVEUP, self._OnMoveUp)  
         EVT_BUTTON(self, ID_LEGEND_MOVEDOWN, self._OnMoveDown)  
         EVT_BUTTON(self, ID_LEGEND_PROPS, self._OnProperties)  
         EVT_BUTTON(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)  
         EVT_BUTTON(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)  
68    
69          panelBox.Add(buttonBox, 0, 0, 4)          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          self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow)          self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow)
109    
110          panelBox.Add(self.tree, 1, wxGROW, 4)          panelBox.Add(self.tree, 1, wxGROW, 0)
111    
112          panelBox.Fit(self)          self.scalebarbitmap = ScaleBarBitmap(self, map, mainWindow)
113            panelBox.Add(self.scalebarbitmap, 0, wxGROW, 0)
114    
115          self.SetAutoLayout(True)          self.SetAutoLayout(True)
116          self.SetSizer(panelBox)          self.SetSizer(panelBox)
117          panelBox.SetSizeHints(self)          panelBox.SetSizeHints(self)
118    
         #panelBox.SetSizeHints(self.parent)  
119    
120          self.panelBox = panelBox          self.panelBox = panelBox
121    
122            self.__EnableButtons(False)
123    
124            self.Create()
125    
126          EVT_CLOSE(self, self._OnClose)          EVT_CLOSE(self, self._OnClose)
127    
128    
# Line 96  class LegendPanel(DockPanel): Line 131  class LegendPanel(DockPanel):
131    
132      def SetMap(self, map):      def SetMap(self, map):
133          self.tree.SetMap(map)          self.tree.SetMap(map)
134            self.scalebarbitmap.SetCanvas(self.mainWindow.canvas)
135    
136      def DoOnSelChanged(self, layer, group):      def DoOnSelChanged(self, layer, group):
137    
138          ok = isinstance(layer, Layer)          ok = isinstance(layer, BaseLayer)
139          self.__EnableButtons(ok)          self.__EnableButtons(ok)
140    
141          if ok:          self.mainWindow.SelectLayer(layer)
             self.mainWindow.SelectLayer(layer)  
142    
143      def DoOnProperties(self):      def DoOnProperties(self):
144          list = self.tree.GetSelectedHierarchy()          list = self.tree.GetSelectedHierarchy()
145    
146          ok = isinstance(list[0], Layer)          ok = isinstance(list[0], BaseLayer)
147          if ok:          if ok:
148              self.mainWindow.OpenLayerProperties(list[0], list[1])              self.mainWindow.OpenLayerProperties(list[0], list[1])
149    
# Line 118  class LegendPanel(DockPanel): Line 153  class LegendPanel(DockPanel):
153      def _OnProperties(self, event):      def _OnProperties(self, event):
154          self.DoOnProperties()          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
# Line 139  class LegendPanel(DockPanel): Line 180  class LegendPanel(DockPanel):
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):      def __Close(self):
192          self.tree.Close()          self.tree.Close()
# Line 155  class LegendTree(wxTreeCtrl): Line 201  class LegendTree(wxTreeCtrl):
201          self.mainWindow = mainWindow          self.mainWindow = mainWindow
202          self.map = None          self.map = None
203          self.parent = parent          self.parent = parent
204          self.layer2id = {}          self.changing_selection = 0
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          EVT_CLOSE(self, self._OnClose)          EVT_CLOSE(self, self._OnClose)
232    
233          self.SetMap(map)          self.SetMap(map)
234    
235        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):      def _OnClose(self, event):
246          self.SetMap(None)          self.SetMap(None)
247    
# Line 178  class LegendTree(wxTreeCtrl): Line 251  class LegendTree(wxTreeCtrl):
251      def SetMap(self, map):      def SetMap(self, map):
252    
253          sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),          sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),
254                      (MAP_LAYERS_ADDED, self._OnMsgMapLayersAddedRemoved),                      (MAP_LAYERS_ADDED, self._OnMsgMapLayersAdded),
255                      (MAP_LAYERS_REMOVED, self._OnMsgMapLayersAddedRemoved)]                      (MAP_LAYERS_REMOVED, self._OnMsgMapLayersRemoved)]
256    
257          if self.map is not None:          if self.map is not None:
258              for msg, func in sub_list: self.map.Unsubscribe(msg, func)              for msg, func in sub_list: self.map.Unsubscribe(msg, func)
# Line 190  class LegendTree(wxTreeCtrl): Line 263  class LegendTree(wxTreeCtrl):
263                      #self._OnMsgMapsChanged)                      #self._OnMsgMapsChanged)
264              #except ConnectorError:              #except ConnectorError:
265                  #pass                  #pass
266              self.__DeleteAllItems()              self.DeleteAllItems()
267                    
268          self.map = map          self.map = map
269    
# Line 202  class LegendTree(wxTreeCtrl): Line 275  class LegendTree(wxTreeCtrl):
275                  #self._OnMsgMapsChanged)                  #self._OnMsgMapsChanged)
276              self.__FillTree(self.map)              self.__FillTree(self.map)
277    
278                    def MoveCurrentItemTop(self):
279      def MoveCurrentItemUp(self):          layer, group = self.GetSelectedHierarchy()
         cur_id = self.GetSelection()  
         assert cur_id.IsOk()  
   
         cur_data = self.GetPyData(cur_id)  
280    
281          #prev_id = self.GetPrevSibling(cur_id)          if layer is not None:
282                self.map.MoveLayerToTop(layer)
283            else:
284                assert False, "Shouldn't be allowed."
285                pass
286    
287          #      def MoveCurrentItemUp(self):
288          # Get out if there's nowhere to go          layer, group = self.GetSelectedHierarchy()
         #  
         #if prev_id == INVALID_TREE_ID: return  
289    
290          if isinstance(cur_data, Layer):          if layer is not None:
291              self.map.RaiseLayer(cur_data)              self.map.RaiseLayer(layer)
         elif isinstance(cur_data, ClassGroup):  
             pass  
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):
         #self.__ShowHideLayer(True)  
326          layer, group = self.GetSelectedHierarchy()          layer, group = self.GetSelectedHierarchy()
327          layer.SetVisible(True)          layer.SetVisible(True)
328    
329      def DoOnHideLayer(self):      def DoOnHideLayer(self):
         #self.__ShowHideLayer(False)  
330          layer, group = self.GetSelectedHierarchy()          layer, group = self.GetSelectedHierarchy()
331          layer.SetVisible(False)          layer.SetVisible(False)
332    
333      def Sort(self):      def Sort(self):
334          self.SortChildren(self.GetRootItem())          self.SortChildren(self.GetRootItem())
335    
336        def GetSelectedHierarchy(self):
337            id = self.GetSelection()
338    
339            if not id.IsOk():
340                return (None, None)
341    
342            layer = self.GetPyData(id)
343            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):      def _OnMsgMapsChanged(self):
354          #print self.map is self.mainWindow.Map()          #print self.map is self.mainWindow.Map()
355          self.SetMap(self.mainWindow.Map())          self.SetMap(self.mainWindow.Map())
356                    
357      def _OnSelChanged(self, event):      def _OnSelChanged(self, event):
358            # 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          layer, group = self.GetSelectedHierarchy()  
389          self.parent.DoOnSelChanged(layer, group)      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.parent.DoOnProperties()          # 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.IsOk()          assert id is not None
415    
416          # XXX: yikes! this is so bad, we should be doing what is          self.__FillTreeLayer(id)
417          #      commented out, but there is a problem with keeping          self.__UpdateSelection()
         #      track of the images in the image list when we replace  
         #      a layer. it ends up causing a seg fault.  
         self.__FillTree(self.map)  
         #self.__FillTreeLayer(id)  
418    
419      def _OnMsgMapStackingChanged(self, *args):      def _OnMsgMapStackingChanged(self, *args):
420          self.Sort()          self.Sort()
# Line 295  class LegendTree(wxTreeCtrl): Line 422  class LegendTree(wxTreeCtrl):
422    
423          if id.IsOk():          if id.IsOk():
424              self.EnsureVisible(id)              self.EnsureVisible(id)
425            self.__UpdateSelection()
426    
427      def _OnMsgMapLayersAddedRemoved(self, map):      def _OnMsgMapLayersAdded(self, map):
428          assert map is self.map          assert map is self.map
429    
430          self.__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      def _OnMsgLayerVisibilityChanged(self, layer):          # Add layers in the map but not in the dict
439          assert isinstance(layer, Layer)          i = 0
440            for l in map.Layers():
441                if not l in layers:
442                    self.__AddLayer(i, l)
443    
444          self.__ShowHideLayer(layer)          self.__UpdateSelection()
445    
446      def GetSelectedHierarchy(self):      def _OnMsgMapLayersRemoved(self, map):
447          id = self.GetSelection()          assert map is self.map
         assert id.IsOk()  
448    
449          layer = self.GetPyData(id)          layers = map.Layers()
         group = None  
450    
451          if isinstance(layer, ClassGroup):          root = self.GetRootItem()
452              id = self.GetItemParent(id)          id, cookie = self.GetFirstChild(root, 0)
453              assert id.IsOk()          while id.IsOk():
454              group = layer              if self.GetPyData(id) not in layers:
455              layer = self.GetPyData(id)                  self.__RemoveLayer(id)
456                id, cookie = self.GetNextChild(root, cookie)
457    
         return (layer, group)  
458    
459      def __FillTree(self, map):          self.__UpdateSelection()
460    
461          assert isinstance(map, Map)      def _OnMsgLayerVisibilityChanged(self, layer):
462            assert isinstance(layer, BaseLayer)
         self.Freeze()  
463    
464          self.__DeleteAllItems()          self.__ShowHideLayer(layer)
465            self.__UpdateSelection()
466    
467          if map.HasLayers():      def _OnMsgLayerTitleChanged(self, layer):
468    
469              self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)          id = self.find_layer(layer)
470                                                                                            if id.IsOk():
471              bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)              self.SetItemText(id, layer.Title())
472              dc = wxMemoryDC()          self.__UpdateSelection()
             dc.SelectObject(bmp)  
             dc.SetBrush(wxBLACK_BRUSH)  
             dc.Clear()  
             dc.SelectObject(wxNullBitmap)  
                                                                                   
             self.emptyImageIndex = \  
                 self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))  
                                                                                   
             self.AssignImageList(self.image_list)  
473    
474              root = self.AddRoot("")      def __UpdateSelection(self):
475            layer, group = self.GetSelectedHierarchy()
476            self.parent.DoOnSelChanged(layer, group)
477            
478        def __FillTree(self, map):
479    
480              for l in map.Layers():          self.Freeze()
                 id = self.PrependItem(root, l.Title())  
                 l.Subscribe(LAYER_CHANGED, self._OnMsgLayerChanged)  
                 l.Subscribe(LAYER_VISIBILITY_CHANGED,  
                             self._OnMsgLayerVisibilityChanged)  
                 self.SetPyData(id, l)  
                 self.__SetVisibilityStyle(l.Visible(), id)  
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 369  class LegendTree(wxTreeCtrl): Line 495  class LegendTree(wxTreeCtrl):
495    
496          self.DeleteChildren(pid)          self.DeleteChildren(pid)
497    
498          clazz = layer.GetClassification()          if layer.HasClassification():
499    
500                clazz = layer.GetClassification()
501    
502          shapeType = layer.ShapeType()              shapeType = layer.ShapeType()
503    
504          show = layer.Visible()              show = layer.Visible()
505          for g in clazz:              for g in clazz:
506              if g.IsVisible():                  if g.IsVisible():
507                  id = self.AppendItem(pid, g.GetDisplayText())                      id = self.AppendItem(pid, g.GetDisplayText())
508                  self.SetPyData(id, g)                      self.SetPyData(id, g)
509                  self.__SetVisibilityStyle(show, id)                      self.__SetVisibilityStyle(show, id)
510    
511                  bmp = self.__BuildGroupImage(g, shapeType)                      bmp = self.__BuildGroupImage(g, shapeType)
512    
513                  if bmp is None:                      if bmp is None:
514                      self.SetItemImage(id, self.emptyImageIndex)                          self.SetItemImage(id, -1)
515                  else:                          self.SetItemSelectedImage(id, -1)
516                      i = self.image_list.Add(bmp)                      else:
517                      self.SetItemImage(id, i)                          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.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 403  class LegendTree(wxTreeCtrl): Line 537  class LegendTree(wxTreeCtrl):
537    
538          return bmp          return bmp
539    
540      def __DeleteAllItems(self):      def DeleteAllItems(self):
541    
542          while len(self.layer2id) > 0:          pid = self.GetRootItem()
             layer, id = self.layer2id.popitem()  
             layer.Unsubscribe(LAYER_CHANGED,  
                               self._OnMsgLayerChanged)  
             layer.Unsubscribe(LAYER_VISIBILITY_CHANGED,  
                               self._OnMsgLayerVisibilityChanged)  
543    
544          self.DeleteAllItems()          id, cookie = self.GetFirstChild(pid, 123)
545            while id.IsOk():
546                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):      def __SetVisibilityStyle(self, visible, id):
617          font = self.GetItemFont(id)          font = self.GetItemFont(id)
# Line 421  class LegendTree(wxTreeCtrl): Line 620  class LegendTree(wxTreeCtrl):
620              font.SetStyle(wxNORMAL)              font.SetStyle(wxNORMAL)
621              color = wxBLACK              color = wxBLACK
622          else:          else:
623              font.SetStyle(wxITALIC)              #font.SetStyle(wxITALIC)
624                font.SetStyle(wxNORMAL)
625              color = wxLIGHT_GREY              color = wxLIGHT_GREY
626    
627          self.SetItemTextColour(id, color)          self.SetItemTextColour(id, color)
628          self.SetItemFont(id, font)          self.SetItemFont(id, font)
629                    
630      def __ShowHideLayer(self, layer):      def __ShowHideLayer(self, layer):
631          parent = self.layer2id[layer]          parent = self.find_layer(layer)
632          assert parent.IsOk()          assert parent.IsOk()
633    
634          visible = layer.Visible()          visible = layer.Visible()
# Line 441  class LegendTree(wxTreeCtrl): Line 641  class LegendTree(wxTreeCtrl):
641              self.__SetVisibilityStyle(visible, id)              self.__SetVisibilityStyle(visible, id)
642              id, cookie = self.GetNextChild(parent, cookie)              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        def SetCanvas(self, canvas):
664            sub_list = [(SCALE_CHANGED, self._OnMsgScaleChanged)]
665    
666            if self.canvas is not None:
667                for msg, func in sub_list: self.canvas.Unsubscribe(msg, func)
668            
669            self.canvas = canvas
670            self.scalebar = ScaleBar(canvas.map)
671    
672            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.639  
changed lines
  Added in v.1241

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26