#!/usr/bin/env python
# ###########################################################################
#
# This file is part of Taurus
#
# http://taurus-scada.org
#
# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
#
# Taurus is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Taurus is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Taurus. If not, see <http://www.gnu.org/licenses/>.
#
# ###########################################################################
"""
nexusWidget.py:
"""
import numpy
import posixpath
from functools import partial
from taurus.external.qt import Qt, compat
from PyMca5.PyMcaGui.io.hdf5 import HDF5Widget, HDF5Info, HDF5DatasetTable
from taurus.qt.qtgui.container import TaurusWidget
from taurus.core.util.log import deprecation_decorator
@deprecation_decorator(rel="5.0.0")
class NeXusInfoWidget(Qt.QTabWidget):
"""deprecated"""
def setInfoDict(self, info):
pass
[docs]
class TaurusNeXusBrowser(TaurusWidget):
"""A Browser for nexus files with optional preview. Based on PyMCA's
HDF5Widget"""
def __init__(self, *args, **kwargs):
TaurusWidget.__init__(self, *args)
fileModel = kwargs.get("fileModel", None)
if fileModel is None:
fileModel = HDF5Widget.FileModel()
self.__fileModel = fileModel
self.treeWidget = HDF5Widget.HDF5Widget(self.__fileModel)
self.treeWidget.setSizePolicy(
Qt.QSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Expanding)
)
# self.infoWidget = HDF5Info.HDF5InfoWidget()
self.__previewStack = Qt.QStackedWidget()
self.__currentPreview = None
# layout
self.__splitter = Qt.QSplitter()
self.__splitter.setOrientation(Qt.Qt.Vertical)
self.__splitter.addWidget(self.treeWidget)
# self.__splitter.addWidget(self.infoWidget)
self.__splitter.addWidget(self.__previewStack)
self.setLayout(Qt.QVBoxLayout())
self.layout().addWidget(self.__splitter)
# Actions
self.setContextMenuPolicy(Qt.Qt.ActionsContextMenu)
self.openFileAction = Qt.QAction(
Qt.QIcon.fromTheme("document-open"), "Open Data File...", self
)
self.togglePreviewAction = Qt.QAction(
Qt.QIcon("actions:view.svg"), "Show/Hide preview", self
)
self.togglePreviewAction.setCheckable(True)
self.togglePreviewAction.setChecked(True)
self.addActions([self.openFileAction, self.togglePreviewAction])
# Toolbar
self._toolbar = Qt.QToolBar("NeXus browser toolbar")
self._toolbar.setIconSize(Qt.QSize(16, 16))
self._toolbar.setFloatable(False)
self._toolbar.addActions(
[self.openFileAction, self.togglePreviewAction]
)
self.layout().setMenuBar(self._toolbar)
# connections
self.__fileModel.sigFileAppended.connect(self.treeWidget.fileAppended)
self.treeWidget.sigHDF5WidgetSignal.connect(self.onHDF5WidgetSignal)
self.openFileAction.triggered.connect(
partial(self.openFile, fname=None)
)
self.togglePreviewAction.toggled.connect(
self.__previewStack.setVisible
)
# configuration
self.registerConfigProperty(
self.togglePreviewAction.isChecked,
self.togglePreviewAction.setChecked,
"showPreview",
)
[docs]
@Qt.pyqtSlot()
@Qt.pyqtSlot("QString")
def openFile(self, fname=None):
if fname is None:
fname, _ = compat.getOpenFileName(self, "Choose NeXus File", "")
if fname:
self.__nexusFile = self.__fileModel.openFile(fname)
[docs]
def findNodeIndex(self, filename, nodename):
nexus_widget = self.neXusWidget()
file_model = nexus_widget.model()
for node in file_model.rootItem.children:
if node.file.filename == filename:
file_node = node
break
else:
raise Exception("Could not find file %s" % filename)
index = file_model.index(file_node.row, 0, Qt.QModelIndex())
node_parts = nodename.split(posixpath.sep)
while node_parts:
name = posixpath.basename(node_parts.pop(0))
for child in node.children:
child_name = posixpath.basename(child.name)
if child_name == name:
node = child
index = file_model.index(node.row, 0, index)
break
else:
raise Exception(
"Could not find node %s in %s" % (name, filename)
)
return index
[docs]
def setCurrentNode(self, filename, nodename):
index = self.findNodeIndex(filename, nodename)
self.setCurrentIndex(index)
[docs]
@classmethod
def getQtDesignerPluginInfo(cls):
ret = TaurusWidget.getQtDesignerPluginInfo()
ret["module"] = "taurus.qt.qtgui.extra_nexus"
ret["icon"] = "designer:listview.png"
ret["container"] = False
ret["group"] = "Taurus Views"
return ret
[docs]
def closeEvent(self, event):
"""Close HDF5 files"""
try:
self.neXusWidget().model().close()
except Exception:
self.warning("Exception received while trying to close HDF5 files")
self.traceback()
TaurusWidget.closeEvent(self, event)
if __name__ == "__main__":
import sys
from taurus.qt.qtgui.application import TaurusApplication
if len(sys.argv) > 1:
fname = sys.argv[1]
else:
fname = None
if len(sys.argv) > 2:
path = sys.argv[2]
else:
path = None
app = TaurusApplication(sys.argv, cmd_line_parser=None)
w = TaurusNeXusBrowser()
w.openFile(fname)
w.show()
if path is not None:
index = w.findNodeIndex(fname, path)
nexus_widget = w.neXusWidget()
nexus_widget.setCurrentIndex(index)
while index.row() != -1 and index.column() != -1:
nexus_widget.expand(index)
index = index.parent()
sys.exit(app.exec_())