CMS 3D CMS Logo

BrowserTabController.py
Go to the documentation of this file.
1 import logging
2 
3 from PyQt4.QtCore import SIGNAL,QPoint
4 from PyQt4.QtGui import QWidget,QMenu
5 
6 from Vispa.Main.TabController import TabController
7 from Vispa.Gui.FindDialog import FindDialog
8 from Vispa.Share.FindAlgorithm import FindAlgorithm
9 from Vispa.Gui.BoxContentDialog import BoxContentDialog
10 from Vispa.Views.AbstractView import AbstractView
11 from Vispa.Plugins.Browser.BrowserTab import BrowserTab
12 from Vispa.Gui.Zoomable import Zoomable
13 
15  """ Controls a tab with a TreeView, an AbstractView and a PropertiesView.
16 
17  The tab is filled using a DataAccessor. The controller supports find
18  functionality as well as a dialog for choosing the box content in the WidgetView.
19  """
20  def __init__(self, plugin):
21  logging.debug(__name__ + ": __init__")
22  TabController.__init__(self, plugin)
23 
24  self._dataAccessor = None
25 
26  self.setFindEnabled()
27  self._findAlgorithm = None
28  self._findDialog = None
29  self._filterAlgoritm = None
30  self._filterDialog = None
31  self._filterObjects = None
32  self._boxContentDialog = BoxContentDialog(self.plugin().application().mainWindow())
33  self.connect(self._boxContentDialog, SIGNAL("scriptChanged"), self.scriptChanged)
34 
35  def centerView(self):
36  if self.tab():
37  return self.tab().centerView()
38  return None
39 
41  if self.tab() and self.tab().centerView():
42  return self.plugin().viewClassId(self.tab().centerView().__class__)
43  return None
44 
45  def enableCenterViewSelectionMenu(self, enable=True, exceptionViewClassId=None):
46  disabledCenterViewIds = []
47  for viewClass in self.plugin().availableCenterViews():
48  viewClassId=self.plugin().viewClassId(viewClass)
49  if enable==False and viewClassId!=exceptionViewClassId:
50  disabledCenterViewIds+=[viewClassId]
51  if enable==True and viewClassId==exceptionViewClassId:
52  disabledCenterViewIds+=[viewClassId]
53  self.plugin().setDisabledCenterViewIds(disabledCenterViewIds)
54 
55  def activated(self):
56  """ Shows view menu when user selects tab.
57  """
58  self.updateViewMenu()
59  self.tab().mainWindow().application().showPluginMenu(self.plugin().viewMenu())
60 
61  def switchCenterView(self, requestedViewClassId):
62  if self.currentCenterViewClassId() == requestedViewClassId:
63  self.updateViewMenu()
64  return True
65  requestedViewClass = None
66  for viewClass in self.plugin().availableCenterViews():
67  if requestedViewClassId == self.plugin().viewClassId(viewClass):
68  requestedViewClass = viewClass
69  if not requestedViewClass and len(self.plugin().availableCenterViews())>0:
70  logging.warning(self.__class__.__name__ +": switchCenterView() - Unknown view class id "+ requestedViewClassId +".")
71  requestedViewClass = self.plugin().availableCenterViews()[0]
72  elif not requestedViewClass:
73  logging.error(self.__class__.__name__ +": switchCenterView() - Unknown view class id "+ requestedViewClassId +". Aborting...")
74  return False
75  self.tab().setCenterView(requestedViewClass())
76  self.updateViewMenu()
77 
78  #reconnect data accessors and stuff
79  if hasattr(self.tab().centerView(), "setEditable"):
80  self.tab().centerView().setEditable(self.isEditable())
82  self.tab().centerView().setFilter(self.filter)
83  selection = self.tab().treeView().selection()
84  if selection:
85  self.tab().centerView().setDataObjects([selection])
86  self.updateCenterView()
87  self.connect(self.tab().centerView(), SIGNAL("selected"), self.onSelected)
88  self.connect(self.tab().centerView(), SIGNAL("modified"), self.setModified)
89  self.connect(self.tab().centerView(), SIGNAL("mouseRightPressed"), self.centerViewMenuButtonClicked)
90  self.saveIni()
91  return True
92 
94  self._boxContentDialog.onScreen()
95 
96  def setEditable(self, edit):
97  """ Makes sure an existing property view's read-only mode is set accordingly.
98  """
99  TabController.setEditable(self, edit)
100  if self.tab() and self.tab().propertyView():
101  self.tab().propertyView().setReadOnly(not edit)
102 
103  def setTab(self, tab):
104  """ Sets tab and connects signals to tab.
105  """
106  if not (isinstance(tab.treeView(), AbstractView) and isinstance(tab.treeView(), QWidget)):
107  raise TypeError(__name__ + " requires a center view of type AbstractView and QWidget.")
108  if not (isinstance(tab.centerView(), AbstractView) and isinstance(tab.centerView(), QWidget)):
109  raise TypeError(__name__ + " requires a center view of type AbstractView and QWidget.")
110  if not isinstance(tab, BrowserTab):
111  raise TypeError(__name__ + " requires a tab of type BrowserTab.")
112  TabController.setTab(self, tab)
113  self.connect(self.tab().treeView(), SIGNAL("selected"), self.onTreeViewSelected)
114  self.connect(self.tab().treeView(), SIGNAL("mouseRightPressed"), self.treeViewMenuButtonClicked)
115  self.connect(self.tab().centerView(), SIGNAL("selected"), self.onSelected)
116  self.connect(self.tab().centerView(), SIGNAL("mouseRightPressed"), self.centerViewMenuButtonClicked)
117  self.connect(self.tab().treeViewHeader(), SIGNAL("mouseRightPressed"), self.treeViewMenuButtonClicked)
118  self.connect(self.tab().centerViewHeader(), SIGNAL("mouseRightPressed"), self.centerViewMenuButtonClicked)
119 
120  if self._dataAccessor:
121  # make sure sub-components of tab also know controller
122  self.setDataAccessor(self._dataAccessor)
123 
124  self.loadIni()
125 
126  def setDataAccessor(self, accessor):
127  """ Set the DataAccessor and show data in the TreeView.
128  """
129  logging.debug(__name__ + ": setDataAccessor")
130  self._dataAccessor = accessor
131  if self.tab():
132  self.tab().treeView().setDataAccessor(self._dataAccessor)
134  self.tab().propertyView().setDataAccessor(self._dataAccessor)
135  self.tab().treeView().setFilter(self.filter)
136  self.tab().centerView().setFilter(self.filter)
137 
138  def dataAccessor(self):
139  return self._dataAccessor
140 
141  def setZoom(self, zoom):
142  """ Sets zoom of tab's scroll area.
143 
144  Needed for zoom tool bar. See TabController setZoom().
145  """
146  if hasattr(self.tab(),"scrollArea"):
147  self.tab().scrollArea().setZoom(zoom)
148 
149  def zoom(self):
150  """ Returns zoom of tab's scoll area.
151 
152  Needed for zoom tool bar. See TabController zoom().
153  """
154  if hasattr(self.tab(),"scrollArea"):
155  return self.tab().scrollArea().zoom()
156  else:
157  return 100.0
158 
159  def updateCenterView(self,propertyView=True):
160  """ Fill the center view from an item in the TreeView and update it """
161  logging.debug(__name__ + ": updateCenterView")
162  statusMessage = self.plugin().application().startWorking("Updating center view")
163  if self.tab().centerView().updateContent():
164  self.tab().centerView().restoreSelection()
165  select = self.tab().centerView().selection()
166  if select != None:
167  if self.tab().propertyView().dataObject() != select and propertyView:
168  self.tab().propertyView().setDataObject(select)
169  self.tab().propertyView().updateContent()
170  self.plugin().application().stopWorking(statusMessage)
171 
172  def onTreeViewSelected(self, select):
173  """ When object is selected in the TreeView update center view and PropertyView.
174  """
175  logging.debug(__name__ + ": onTreeViewSelected")
176  self.onSelected(select)
177  self.tab().centerView().setDataObjects([self.tab().treeView().selection()])
178  self.updateCenterView()
179 
180  def onSelected(self, select):
181  """ When object is selected in the center view update PropertyView.
182  """
183  logging.debug(__name__ + ": onSelected")
184  if self.tab().propertyView().dataObject() != select:
185  statusMessage = self.plugin().application().startWorking("Updating property view")
186  self.tab().propertyView().setDataObject(select)
187  self.tab().propertyView().updateContent()
188  self.plugin().application().stopWorking(statusMessage)
189 
190  def updateContent(self, filtered=False, propertyView=True):
191  """ Updates all three views and restores the selection, e.g. after moving to next event.
192  """
193  logging.debug(__name__ + ": updateContent")
194  # run filter if used
195  if self._filterDialog and not filtered:
196  self._filterAlgoritm.setDataObjects(self._dataAccessor.topLevelObjects())
197  self._filterDialog.filter()
198  return
199  statusMessage = self.plugin().application().startWorking("Updating all views")
200  if self._findAlgorithm:
201  self._findAlgorithm.setDataObjects(self._dataAccessor.topLevelObjects())
202  self._findDialog.edited()
203  self.tab().treeView().setDataObjects(self._dataAccessor.topLevelObjects())
204  if self.updateTreeView():
205  if propertyView:
206  self.tab().propertyView().setDataObject(self.tab().treeView().selection())
207  if not propertyView or self.tab().propertyView().updateContent():
208  selection = self.tab().treeView().selection()
209  if selection:
210  self.tab().centerView().setDataObjects([selection])
211  self.updateCenterView(propertyView)
212  self.plugin().application().stopWorking(statusMessage)
213 
214  def updateTreeView(self):
215  if self.tab().treeView().updateContent():
216  self.tab().treeView().restoreSelection()
217  return True
218  else:
219  return False
220 
221  def find(self):
222  """ Open find dialog and find items.
223  """
224  logging.debug(__name__ + ": find")
225  if not self._findAlgorithm:
227  self._findAlgorithm.setDataAccessor(self._dataAccessor)
228  self._findAlgorithm.setFilter(self.filter)
229  if not self._findDialog:
230  self._findDialog = FindDialog(self.tab())
231  self._findDialog.setFindAlgorithm(self._findAlgorithm)
232  self.connect(self._findDialog, SIGNAL("found"), self.select)
233  self._findAlgorithm.setDataObjects(self._dataAccessor.topLevelObjects())
234  self._findDialog.onScreen()
235 
236  def filterDialog(self):
237  """ Open filter dialog and filter items.
238  """
239  logging.debug(__name__ + ": filterDialog")
240  if not self._filterAlgoritm:
242  self._filterAlgoritm.setDataAccessor(self._dataAccessor)
243  if not self._filterDialog:
244  self._filterDialog = FindDialog(self.tab())
245  self._filterDialog.setFindAlgorithm(self._filterAlgoritm)
246  self.connect(self._filterDialog, SIGNAL("filtered"), self.filtered)
247  self._filterAlgoritm.setDataObjects(self._dataAccessor.topLevelObjects())
248  self._filterDialog.onScreen(True, False)
249 
250  def filtered(self, filterObjects):
251  self._filterObjects = filterObjects
252  self.updateContent(True)
253 
254  def select(self, object):
255  """ Select an object in all views.
256  """
257  logging.debug(__name__ + ": select : " + str(object))
258  self.tab().treeView().select(object)
259  self.tab().centerView().select(object)
260  if self.tab().propertyView().dataObject() != object:
261  statusMessage = self.plugin().application().startWorking("Updating property view")
262  self.tab().propertyView().setDataObject(object)
263  self.tab().propertyView().updateContent()
264  self.plugin().application().stopWorking(statusMessage)
265 
266  def scriptChanged(self, script):
267  """ Update box content of center view when script is changed.
268  """
269  if hasattr(self.tab().centerView(), "setBoxContentScript"):
270  self.tab().centerView().setBoxContentScript(script)
271  self.updateCenterView()
272 
273  def close(self):
274  self.cancel()
275  return TabController.close(self)
276 
277  def boxContentDialog(self):
278  return self._boxContentDialog
279 
280  def saveImage(self, filename=None):
281  """ Save screenshot of the center view to file.
282  """
283  self.tab().centerView().exportImage(filename)
284 
285  def filter(self, objects):
286  """ Filter all final state objects using the output of the filterDialog.
287  """
288  #logging.debug(__name__ + ": filter")
289  if self._filterObjects != None:
290  return [o for o in objects if o in self._filterObjects or len(self.filter(self._dataAccessor.children(o)))>0]
291  else:
292  return objects
293 
294  def cancel(self):
295  """ Cancel all operations in tab.
296  """
297  logging.debug(__name__ + ": cancel")
298  self.tab().treeView().cancel()
299  self.tab().centerView().cancel()
300  self.tab().propertyView().cancel()
301 
302  def isBusy(self):
303  return self.tab().treeView().isBusy() or\
304  self.tab().centerView().isBusy() or\
305  self.tab().propertyView().isBusy()
306 
307  def saveIni(self):
308  """ write options to ini """
309  logging.debug(__name__ + ": saveIni")
310  if not self.plugin():
311  logging.waring(self.__class__.__name__ +": saveIni() - No plugin set. Aborting...")
312  return
313  ini = self.plugin().application().ini()
314  if not ini.has_section("view"):
315  ini.add_section("view")
316  if self.currentCenterViewClassId():
317  ini.set("view", "CurrentView", self.currentCenterViewClassId())
318  if hasattr(self.centerView(), "boxContentScript"):
319  ini.set("view", "box content script", self.centerView().boxContentScript())
320  self.plugin().application().writeIni()
321 
322  def loadIni(self):
323  """ read options from ini """
324  logging.debug(__name__ + ": loadIni")
325  ini = self.plugin().application().ini()
326  if ini.has_option("view", "CurrentView"):
327  proposed_view = ini.get("view", "CurrentView")
328  self.switchCenterView(proposed_view)
329  elif self.plugin().defaultCenterViewId():
330  self.switchCenterView(self.plugin().defaultCenterViewId())
331  elif len(self.plugin().availableCenterViews()) > 0:
332  self.switchCenterView(self.plugin().viewClassId(self.plugin().availableCenterViews()[0]))
333  if ini.has_option("view", "box content script"):
334  self._boxContentDialog.setScript(str(ini.get("view", "box content script")))
335  if hasattr(self.centerView(), "setBoxContentScript"):
336  self.centerView().setBoxContentScript(str(ini.get("view", "box content script")))
337 
338  def updateViewMenu(self):
339  """ Enable/disable menu entries, when center view changes.
340  """
341  self.plugin().boxContentAction().setVisible(hasattr(self.tab().centerView(),"setBoxContentScript"))
342  self.plugin().saveImageAction().setVisible(hasattr(self.tab().centerView(),"exportImage"))
343  self.plugin().zoomAction().setVisible(hasattr(self.tab().centerView(),"setZoom"))
344  self.plugin().expandAllAction().setVisible(hasattr(self.tab().treeView(),"expandAll"))
345  self.plugin().expandToDepthAction().setVisible(hasattr(self.tab().treeView(),"expandToDepth"))
346  self.plugin().collapseAllAction().setVisible(hasattr(self.tab().treeView(),"collapseAll"))
347  for action in self.plugin().viewMenu().actions():
348  if action.data().toString()!="":
349  action.setEnabled(not action.data().toString() in self.plugin().disabledCenterViewIds())
350  currentAction=action.data().toString()==self.currentCenterViewClassId()
351  action.setChecked(currentAction)
352  if currentAction:
353  self.tab().setCenterViewHeader(action.text().replace("&",""))
354  if self.tab().mainWindow():
355  if isinstance(self.tab().centerView(), Zoomable):
356  self.tab().mainWindow().application().showZoomToolBar()
357  else:
358  self.tab().mainWindow().application().hideZoomToolBar()
359 
360  def centerViewMenuButtonClicked(self, point=None):
361  popup=QMenu(self.tab().centerViewMenuButton())
362  popup.addAction(self.plugin()._boxContentAction)
363  popup.addAction(self.plugin()._saveImageAction)
364  popup.addAction(self.plugin()._zoomAction)
365  popup.addSeparator()
366  for action in self.plugin().viewMenu().actions():
367  if action.data().toString()!="":
368  popup.addAction(action)
369  if not isinstance(point,QPoint):
370  point=self.tab().centerViewMenuButton().mapToGlobal(QPoint(self.tab().centerViewMenuButton().width(),0))
371  popup.exec_(point)
372 
373  def treeViewMenuButtonClicked(self, point=None):
374  popup=QMenu(self.tab().treeViewMenuButton())
375  popup.addAction(self.plugin()._expandAllAction)
376  popup.addAction(self.plugin()._expandToDepthAction)
377  popup.addAction(self.plugin()._collapseAllAction)
378  popup.addAction(self.plugin()._filterAction)
379  popup.addSeparator()
380  if not isinstance(point,QPoint):
381  point=self.tab().treeViewMenuButton().mapToGlobal(QPoint(self.tab().treeViewMenuButton().width(),0))
382  popup.exec_(point)
roAction_t actions[nactions]
Definition: GenABIO.cc:187
def setFindEnabled(self, enable=True)
selection
main part
Definition: corrVsCorr.py:99
def replace(string, replacements)
def setModified(self, modified=True)
std::string toString(const char *format,...)
Definition: xdaq_compat.cc:4
def enableCenterViewSelectionMenu(self, enable=True, exceptionViewClassId=None)
#define str(s)
def updateContent(self, filtered=False, propertyView=True)