CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TreeView.py
Go to the documentation of this file.
1 import logging
2 
3 from PyQt4.QtCore import Qt,SIGNAL,QCoreApplication
4 from PyQt4.QtGui import QTreeWidget,QTreeWidgetItem,QInputDialog
5 
6 from Vispa.Main.Application import Application
7 from Vispa.Share.BasicDataAccessor import BasicDataAccessor
8 from Vispa.Views.AbstractView import AbstractView
9 
10 class TreeView(AbstractView, QTreeWidget):
11  """ The TreeView widget fills itself using a DataAccessor.
12  """
13 
14  LABEL = "&Tree View"
15  UPDATE_EVERY = 20
16 
17  def __init__(self, parent=None, maxDepth=100):
18  logging.debug(__name__ + ": __init__")
19  AbstractView.__init__(self)
20  QTreeWidget.__init__(self, parent)
21 
22  self._operationId = 0
23  self._firstItem = None
24  self._itemDict = {}
25  self._maxDepth = maxDepth
26  self._selection = None
27  self._updatingFlag = 0
28  self._treeDepth=1
30 
31  self.setSortingEnabled(False)
32  self.setColumnCount(1)
33  self.setRootIsDecorated(True)
34  self.header().hide()
35 
36  self.connect(self, SIGNAL("itemSelectionChanged()"), self.itemSelectionChanged)
37  self.connect(self, SIGNAL("itemCollapsed(QTreeWidgetItem*)"), self.itemExpanded)
38  self.connect(self, SIGNAL("itemExpanded(QTreeWidgetItem*)"), self.itemExpanded)
39 
40  def setDataAccessor(self, accessor):
41  """ Sets the DataAccessor from which the nodes are created.
42 
43  You need to call updateContent() in order to make the changes visible.
44  """
45  if not isinstance(accessor, BasicDataAccessor):
46  raise TypeError(__name__ + " requires data accessor of type BasicDataAccessor.")
47  AbstractView.setDataAccessor(self, accessor)
48 
49  def cancel(self):
50  """ Stop all running operations.
51  """
52  self._operationId += 1
53 
54  def clear(self):
55  """ Deletes all items in the TreeView
56  """
57  #logging.debug(__name__ + ": clear")
58  self._itemDict = {}
59  self._firstItem = None
60  QTreeWidget.clear(self)
61 
62  def updateContent(self):
63  """ Clear the TreeView and refill it.
64  """
65  #logging.debug(__name__ + ": updateContent")
66  self.cancel()
67  if self.dataAccessor() == None:
68  return False
69  self._updatingFlag+=1
70  self.clear()
71  if self.dataObject()==None:
72  self._updatingFlag-=1
73  return True
74  operationId = self._operationId
75  i = 0
76  for object in self.applyFilter(self.dataObjects()):
77  # Process application event loop in order to accept user input during time consuming drawing operation
78  self._updateCounter+=1
79  if self._updateCounter>=self.UPDATE_EVERY:
80  self._updateCounter=0
81  if not Application.NO_PROCESS_EVENTS:
82  QCoreApplication.instance().processEvents()
83  # Abort drawing if operationId out of date
84  if operationId != self._operationId:
85  break
86  self._createNode(object, self, str(i))
87  i += 1
88  if self._treeDepth>0:
89  self.expandToDepth(self._treeDepth-1)
90  self._updatingFlag -=1
91  return self._operationId==operationId
92 
93  def _createNode(self, object=None, itemParent=None, positionName="0"):
94  """ Create daughter items of an object recursively.
95  """
96  item = QTreeWidgetItem(itemParent)
97  item.setText(0, self.dataAccessor().label(object))
98  item.object = object
99  item.positionName = str(positionName)+"("+self.dataAccessor().label(object)+")"
100  self._itemDict[item.positionName] = item
101  if self._firstItem==None:
102  self._firstItem=item
103  i = 0
104  if len(positionName.split("-")) < self._maxDepth:
105  for daughter in self.applyFilter(self.dataAccessor().children(object)):
106  self._createNode(daughter, item, positionName + "-" + str(i))
107  i += 1
108 
110  """ Emits signal selected that the TabController can connect to.
111  """
112  #logging.debug(__name__ + ": itemSelectionChanged")
113  if not self._updatingFlag:
114  self._selection = self.currentItem().positionName
115  self.emit(SIGNAL("selected"), self.currentItem().object)
116 
117  def select(self, object):
118  """ Mark an object in the TreeView as selected.
119  """
120  #logging.debug(__name__ + ": select")
121  items = []
122  for positionName, item in self._itemDict.items():
123  if item.object == object:
124  items += [(positionName, item)]
125  if len(items) > 0:
126  item = sorted(items)[0][1]
127  self._selection = item.positionName
128  self._updatingFlag +=1
129  self.setCurrentItem(item)
130  self._updatingFlag -=1
131 
132  def _selectedItem(self):
133  if self._selection in self._itemDict.keys():
134  return self._itemDict[self._selection]
135  elif self._firstItem!=None:
136  return self._firstItem
137  else:
138  return None
139 
140  def restoreSelection(self):
141  """ Restore selection.
142  """
143  #logging.debug(__name__ + ": restoreSelection")
144  select = self._selectedItem()
145  if select != None:
146  self._updatingFlag +=1
147  self.setCurrentItem(select)
148  self._updatingFlag -=1
149 
150  def selection(self):
151  """ Return currently selected object.
152 
153  If selection unknown return first object.
154  """
155  #logging.debug(__name__ + ": selection")
156  select = self._selectedItem()
157  if select != None:
158  return select.object
159  else:
160  return None
161 
162  def isBusy(self):
163  return self._updatingFlag>0
164 
165  def mousePressEvent(self,event):
166  QTreeWidget.mousePressEvent(self,event)
167  if event.button()==Qt.RightButton:
168  self.emit(SIGNAL("mouseRightPressed"), event.globalPos())
169 
171  """ Show dialog and call expandToDepth() function of tree view.
172  """
173  if hasattr(QInputDialog, "getInteger"):
174  # Qt 4.3
175  (depth, ok) = QInputDialog.getInteger(self, "Expand to depth...", "Input depth:", self._treeDepth, 0)
176  else:
177  # Qt 4.5
178  (depth, ok) = QInputDialog.getInt(self, "Expand to depth...", "Input depth:", self._treeDepth, 0)
179  if ok:
180  self._treeDepth=depth
181  self.collapseAll(False)
182  if self._treeDepth>0:
183  self.expandToDepth(self._treeDepth-1)
184 
185  def expandAll(self):
186  self._treeDepth=10000
187  QTreeWidget.expandAll(self)
188 
189  def collapseAll(self,remember=True):
190  if remember:
191  self._treeDepth=0
192  QTreeWidget.collapseAll(self)
193 
194  def itemExpanded(self,item):
195  i=0
196  while item:
197  if item.isExpanded():
198  i+=1
199  item=item.parent()
200  self._treeDepth=i
201