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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26