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

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

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

revision 217 by bh, Wed Jul 17 10:50:40 2002 UTC revision 2700 by dpinte, Mon Sep 18 14:27:02 2006 UTC
# Line 1  Line 1 
1  #! /usr/bin/python  # Copyright (c) 2001, 2002, 2003 by Intevation GmbH
 # Copyright (c) 2001, 2002 by Intevation GmbH  
2  # Authors:  # Authors:
3  # Jan-Oliver Wagner <[email protected]>  # Jan-Oliver Wagner <[email protected]>
4  # Bernhard Herzog <[email protected]>  # Bernhard Herzog <[email protected]>
# Line 9  Line 8 
8    
9  __version__ = "$Revision$"  __version__ = "$Revision$"
10    
11  from types import StringType  from types import StringType, UnicodeType
12    
13  from wxPython.wx import *  import wx
14    
15  from Thuban.Model.messages import MAPS_CHANGED, MAP_PROJECTION_CHANGED, \  from Thuban import _
16       LAYERS_CHANGED, LAYER_LEGEND_CHANGED, LAYER_VISIBILITY_CHANGED, \  from Thuban.UI.common import Color2wxColour
17       EXTENSIONS_CHANGED, EXTENSION_OBJECTS_CHANGED  
18  from Thuban.Model.layer import Layer, shapetype_names  from Thuban.Model.color import Color
19    
20    from Thuban.Model.messages import CHANGED
21    from Thuban.Model.layer import Layer
22  from Thuban.Model.map import Map  from Thuban.Model.map import Map
23    
24  from dialogs import NonModalDialog  from dialogs import NonModalNonParentDialog
25  from messages import SESSION_CHANGED, SELECTED_LAYER  from messages import SESSION_REPLACED, LAYER_SELECTED
26    
27    BMP_SIZE = 15
28    
29  class SessionTreeCtrl(wxTreeCtrl):  class SessionTreeCtrl(wx.TreeCtrl):
30    
31      """Widget to display a tree view of the session.      """Widget to display a tree view of the session.
32    
# Line 45  class SessionTreeCtrl(wxTreeCtrl): Line 48  class SessionTreeCtrl(wxTreeCtrl):
48            value of TreeInfo.            value of TreeInfo.
49      """      """
50    
51      # the session channels to subscribe to update the tree      def __init__(self, parent, ID, mainwindow, app):
     session_channels = (MAPS_CHANGED, MAP_PROJECTION_CHANGED,  
                         LAYERS_CHANGED, LAYER_LEGEND_CHANGED,  
                         LAYER_VISIBILITY_CHANGED, EXTENSIONS_CHANGED,  
                         EXTENSION_OBJECTS_CHANGED)  
52    
     def __init__(self, parent, ID, app):  
53          # Use the WANTS_CHARS style so the panel doesn't eat the Return key.          # Use the WANTS_CHARS style so the panel doesn't eat the Return key.
54          wxTreeCtrl.__init__(self, parent, ID)          wx.TreeCtrl.__init__(self, parent, ID)
55    
56            self.mainwindow = mainwindow
57          self.app = app          self.app = app
58          # boolean to indicate that we manipulate the selection ourselves          # boolean to indicate that we manipulate the selection ourselves
59          # so that we can ignore the selection events generated          # so that we can ignore the selection events generated
# Line 63  class SessionTreeCtrl(wxTreeCtrl): Line 62  class SessionTreeCtrl(wxTreeCtrl):
62          # Dictionary mapping layer id's to tree items          # Dictionary mapping layer id's to tree items
63          self.layer_to_item = {}          self.layer_to_item = {}
64    
65          self.app.Subscribe(SESSION_CHANGED, self.session_changed)          self.app.Subscribe(SESSION_REPLACED, self.session_changed)
66          self.app.interactor.Subscribe(SELECTED_LAYER, self.layer_selected)          self.mainwindow.Subscribe(LAYER_SELECTED, self.layer_selected)
67    
68          # the session currently displayed in the tree          # the session currently displayed in the tree
69          self.session = None          self.session = None
70    
71    
72          # pretend the session has changed to build the initial tree          # pretend the session has changed to build the initial tree
73          self.session_changed()          self.session_changed()
74    
75          EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)          self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, id=self.GetId())
76    
77      def unsubscribe_all(self):      def unsubscribe_all(self):
78          if self.session is not None:          if self.session is not None:
79              for channel in self.session_channels:              self.session.Unsubscribe(CHANGED, self.update_tree)
                 self.session.Unsubscribe(channel, self.update_tree)  
80              self.session = None              self.session = None
81          self.app.Unsubscribe(SESSION_CHANGED, self.session_changed)          self.app.Unsubscribe(SESSION_REPLACED, self.session_changed)
82          self.app.interactor.Unsubscribe(SELECTED_LAYER, self.layer_selected)          self.mainwindow.Unsubscribe(LAYER_SELECTED, self.layer_selected)
83    
84      def update_tree(self, *args):      def update_tree(self, *args):
85          """Clear and rebuild the tree"""          """Clear and rebuild the tree"""
86          self.DeleteAllItems()          self.DeleteAllItems()
87          self.layer_to_item.clear()          self.layer_to_item.clear()
88            self.image_list = wx.ImageList(BMP_SIZE, BMP_SIZE, False, 0)
89    
90            bmp = wx.EmptyBitmap(BMP_SIZE, BMP_SIZE)
91            dc = wx.MemoryDC()
92            dc.SelectObject(bmp)
93            dc.SetBrush(wx.BLACK_BRUSH)
94            dc.Clear()
95            dc.SelectObject(wx.NullBitmap)
96    
97            self.emptyImageIndex = \
98                self.image_list.AddWithColourMask(bmp, wx.Colour(0, 0, 0))
99    
100            self.AssignImageList(self.image_list)
101    
102          session = self.app.session          session = self.app.session
103          info = session.TreeInfo()          info = session.TreeInfo()
104          root = self.AddRoot(info[0])          root = self.AddRoot(info[0], -1, -1, None)
105            self.SetItemImage(root, self.emptyImageIndex)
106          self.add_items(root, info[1])          self.add_items(root, info[1])
107          self.Expand(root)          self.Expand(root)
108          # select the selected layer          # select the selected layer
109          selected_layer = self.app.interactor.selected_layer          selected_layer = self.mainwindow.current_layer()
110          if selected_layer is not None:          if selected_layer is not None:
111              self.SelectItem(self.layer_to_item[id(selected_layer)])              # One would expect that the selected_layer's id is in
112                # layer_to_item at this point as we've just rebuilt that
113                # mapping completely. However, when a new session is loaded
114                # for instance, it can happen that the tree view is updated
115                # before the canvas's selection in which case selected_layer
116                # may be a layer of the old session.
117                item = self.layer_to_item.get(id(selected_layer))
118                if item is not None:
119                    self.SelectItem(item)
120    
121      def add_items(self, parent, items):      def add_items(self, parent, items):
122    
123            if items is None: return
124    
125          for item in items:          for item in items:
126              if hasattr(item, "TreeInfo"):              if hasattr(item, "TreeInfo"):
127                  # Supports the TreeInfo protocol                  # Supports the TreeInfo protocol
128                  info = item.TreeInfo()                  info = item.TreeInfo()
129                  treeitem = self.AppendItem(parent, info[0])                  treeitem = self.AppendItem(parent, info[0], -1, -1, None)
130                    self.SetItemImage(treeitem, self.emptyImageIndex)
131                  self.SetPyData(treeitem, item)                  self.SetPyData(treeitem, item)
132                  self.add_items(treeitem, info[1])                  self.add_items(treeitem, info[1])
133                  self.Expand(treeitem)                  self.Expand(treeitem)
134                  if isinstance(item, Layer):                  if isinstance(item, Layer):
135                      self.layer_to_item[id(item)] = treeitem                      self.layer_to_item[id(item)] = treeitem
136              elif isinstance(item, StringType):              elif isinstance(item, StringType) or \
137                     isinstance(item, UnicodeType):
138                  # it's a string                  # it's a string
139                  # FIXME: What to do about UNICODE                  treeitem = self.AppendItem(parent, item, -1, -1, None)
140                  self.AppendItem(parent, item)                  self.SetItemImage(treeitem, self.emptyImageIndex)
141              else:              else:
142                  # assume its a sequence (title, items)                  # assume its a sequence (title, items)
143                  treeitem = self.AppendItem(parent, item[0])                  if isinstance(item[1], Color):
144                  self.add_items(treeitem, item[1])  
145                        treeitem = self.AppendItem(parent, "(%s)" % item[0])
146    
147                        bmp = wx.EmptyBitmap(BMP_SIZE, BMP_SIZE)
148                        brush = wx.Brush(Color2wxColour(item[1]), wx.SOLID)
149                        dc = wx.MemoryDC()
150                        dc.SelectObject(bmp)
151                        dc.SetBrush(brush)
152                        dc.Clear()
153                        dc.DrawRoundedRectangle(0, 0,
154                                                bmp.GetWidth(), bmp.GetHeight(),
155                                                4)
156                        dc.SelectObject(wx.NullBitmap)
157    
158                        i = self.image_list.Add(bmp)
159                        self.SetItemImage(treeitem, i)
160                    else:
161                        treeitem = self.AppendItem(parent, item[0], -1, -1, None)
162                        self.SetItemImage(treeitem, self.emptyImageIndex)
163                        self.add_items(treeitem, item[1])
164                  self.Expand(treeitem)                  self.Expand(treeitem)
165    
166      def session_changed(self, *args):      def session_changed(self, *args):
# Line 123  class SessionTreeCtrl(wxTreeCtrl): Line 168  class SessionTreeCtrl(wxTreeCtrl):
168          # if the session has changed subscribe/unsubscribe          # if the session has changed subscribe/unsubscribe
169          if self.session is not new_session:          if self.session is not new_session:
170              if self.session is not None:              if self.session is not None:
171                  for channel in self.session_channels:                  self.session.Unsubscribe(CHANGED, self.update_tree)
                     self.session.Unsubscribe(channel, self.update_tree)  
172              if new_session is not None:              if new_session is not None:
173                  for channel in self.session_channels:                  new_session.Subscribe(CHANGED, self.update_tree)
                     new_session.Subscribe(channel, self.update_tree)  
174              self.session = new_session              self.session = new_session
175          self.update_tree()          self.update_tree()
176    
# Line 139  class SessionTreeCtrl(wxTreeCtrl): Line 182  class SessionTreeCtrl(wxTreeCtrl):
182              if isinstance(object, Layer) or isinstance(object, Map):              if isinstance(object, Layer) or isinstance(object, Map):
183                  break                  break
184              item = self.GetItemParent(item)              item = self.GetItemParent(item)
185            else:
186                # No layer or map was found in the chain of parents, so
187                # there's nothing we can do.
188                return
189    
190          self.changing_selection = 1          self.changing_selection = 1
191          try:          try:
# Line 161  class SessionTreeCtrl(wxTreeCtrl): Line 208  class SessionTreeCtrl(wxTreeCtrl):
208              return              return
209          self.normalize_selection()          self.normalize_selection()
210          # SelectedLayer returns None if no layer is selected. Since          # SelectedLayer returns None if no layer is selected. Since
211          # passing None to interactor.SelectLayer deselects the layer we          # passing None to SelectLayer deselects the layer we can simply
212          # can simply pass the result of SelectedLayer on in all cases          # pass the result of SelectedLayer on in all cases
213          self.app.interactor.SelectLayer(self.SelectedLayer())          self.mainwindow.SelectLayer(self.SelectedLayer())
214    
215      def layer_selected(self, layer):      def layer_selected(self, layer):
216          item = self.layer_to_item.get(id(layer))          item = self.layer_to_item.get(id(layer))
# Line 171  class SessionTreeCtrl(wxTreeCtrl): Line 218  class SessionTreeCtrl(wxTreeCtrl):
218              self.SelectItem(item)              self.SelectItem(item)
219    
220    
221  class SessionTreeView(NonModalDialog):  class SessionTreeView(NonModalNonParentDialog):
222    
223      """Non modal dialog showing the session as a tree"""      """Non modal dialog showing the session as a tree"""
224    
225      def __init__(self, parent, app, name):      def __init__(self, parent, app, name):
226          NonModalDialog.__init__(self, parent, app.interactor, name, "Session")          NonModalNonParentDialog.__init__(self, parent, name, _("Session"))
227          self.tree = SessionTreeCtrl(self, -1, app)          self.tree = SessionTreeCtrl(self, -1, parent, app)
228    
229      def OnClose(self, event):      def OnClose(self, event):
230          #self.interactor.Unsubscribe(SELECTED_SHAPE, self.select_shape)          NonModalNonParentDialog.OnClose(self, event)
         NonModalDialog.OnClose(self, event)  
231    
232          # if there were a way to get notified when the tree control          # if there were a way to get notified when the tree control
233          # itself is destroyed we could use that to unsubscribe instead          # itself is destroyed we could use that to unsubscribe instead
234          # of doing it here. (EVT_WINDOW_DESTROY doesn't seem to sent at          # of doing it here. (EVT_WINDOW_DESTROY doesn't seem to sent at
235          # all)          # all)
236          self.tree.unsubscribe_all()          self.tree.unsubscribe_all()
237    

Legend:
Removed from v.217  
changed lines
  Added in v.2700

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26