diff options
Diffstat (limited to 'silx/gui/data/Hdf5TableView.py')
-rw-r--r-- | silx/gui/data/Hdf5TableView.py | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/silx/gui/data/Hdf5TableView.py b/silx/gui/data/Hdf5TableView.py index e4a0747..04199b2 100644 --- a/silx/gui/data/Hdf5TableView.py +++ b/silx/gui/data/Hdf5TableView.py @@ -30,8 +30,9 @@ from __future__ import division __authors__ = ["V. Valls"] __license__ = "MIT" -__date__ = "10/10/2017" +__date__ = "23/05/2018" +import collections import functools import os.path import logging @@ -41,6 +42,7 @@ from .TextFormatter import TextFormatter import silx.gui.hdf5 from silx.gui.widgets import HierarchicalTableView from ..hdf5.Hdf5Formatter import Hdf5Formatter +from ..hdf5._utils import htmlFromDict try: import h5py @@ -54,7 +56,7 @@ _logger = logging.getLogger(__name__) class _CellData(object): """Store a table item """ - def __init__(self, value=None, isHeader=False, span=None): + def __init__(self, value=None, isHeader=False, span=None, tooltip=None): """ Constructor @@ -65,6 +67,7 @@ class _CellData(object): self.__value = value self.__isHeader = isHeader self.__span = span + self.__tooltip = tooltip def isHeader(self): """Returns true if the property is a sub-header title. @@ -85,6 +88,19 @@ class _CellData(object): """ return self.__span + def tooltip(self): + """Returns the tooltip of the item. + + :rtype: tuple + """ + return self.__tooltip + + def invalidateValue(self): + self.__value = None + + def invalidateToolTip(self): + self.__tooltip = None + class _TableData(object): """Modelize a table with header, row and column span. @@ -143,7 +159,7 @@ class _TableData(object): item = _CellData(value=headerLabel, isHeader=True, span=(1, self.__colCount)) self.__data.append([item]) - def addHeaderValueRow(self, headerLabel, value): + def addHeaderValueRow(self, headerLabel, value, tooltip=None): """Append the table with a row using the first column as an header and other cells as a single cell for the value. @@ -151,7 +167,7 @@ class _TableData(object): :param object value: value to store. """ header = _CellData(value=headerLabel, isHeader=True) - value = _CellData(value=value, span=(1, self.__colCount)) + value = _CellData(value=value, span=(1, self.__colCount), tooltip=tooltip) self.__data.append([header, value]) def addRow(self, *args): @@ -214,7 +230,20 @@ class Hdf5TableModel(HierarchicalTableView.HierarchicalTableModel): elif role == qt.Qt.DisplayRole: value = cell.value() if callable(value): - value = value(self.__obj) + try: + value = value(self.__obj) + except Exception: + cell.invalidateValue() + raise + return value + elif role == qt.Qt.ToolTipRole: + value = cell.tooltip() + if callable(value): + try: + value = value(self.__obj) + except Exception: + cell.invalidateToolTip() + raise return value return None @@ -260,6 +289,14 @@ class Hdf5TableModel(HierarchicalTableView.HierarchicalTableModel): """Format the HDF5 type""" return self.__hdf5Formatter.humanReadableHdf5Type(dataset) + def __attributeTooltip(self, attribute): + attributeDict = collections.OrderedDict() + if hasattr(attribute, "shape"): + attributeDict["Shape"] = self.__hdf5Formatter.humanReadableShape(attribute) + attributeDict["Data type"] = self.__hdf5Formatter.humanReadableType(attribute, full=True) + html = htmlFromDict(attributeDict, title="HDF5 Attribute") + return html + def __formatDType(self, dataset): """Format the numpy dtype""" return self.__hdf5Formatter.humanReadableType(dataset, full=True) @@ -310,7 +347,8 @@ class Hdf5TableModel(HierarchicalTableView.HierarchicalTableModel): # it's a real H5py object self.__data.addHeaderValueRow("Basename", lambda x: os.path.basename(x.name)) self.__data.addHeaderValueRow("Name", lambda x: x.name) - self.__data.addHeaderValueRow("File", lambda x: x.file.filename) + if obj.file is not None: + self.__data.addHeaderValueRow("File", lambda x: x.file.filename) if hasattr(obj, "path"): # That's a link @@ -322,8 +360,11 @@ class Hdf5TableModel(HierarchicalTableView.HierarchicalTableModel): else: if silx.io.is_file(obj): physical = lambda x: x.filename + SEPARATOR + x.name + elif obj.file is not None: + physical = lambda x: x.file.filename + SEPARATOR + x.name else: - physical = lambda x: x.file.filename + SEPARATOR + x.name + # Guess it is a virtual node + physical = "No physical location" self.__data.addHeaderValueRow("Physical", physical) if hasattr(obj, "dtype"): @@ -367,7 +408,10 @@ class Hdf5TableModel(HierarchicalTableView.HierarchicalTableModel): self.__data.addHeaderRow(headerLabel="Attributes") for key in sorted(obj.attrs.keys()): callback = lambda key, x: self.__formatter.toString(x.attrs[key]) - self.__data.addHeaderValueRow(headerLabel=key, value=functools.partial(callback, key)) + callbackTooltip = lambda key, x: self.__attributeTooltip(x.attrs[key]) + self.__data.addHeaderValueRow(headerLabel=key, + value=functools.partial(callback, key), + tooltip=functools.partial(callbackTooltip, key)) def __get_filter_info(self, dataset, filterIndex): """Get a tuple of readable info from dataset filters @@ -447,7 +491,7 @@ class Hdf5TableView(HierarchicalTableView.HierarchicalTableView): def setData(self, data): """Set the h5py-like object exposed by the model - :param h5pyObject: A h5py-like object. It can be a `h5py.Dataset`, + :param data: A h5py-like object. It can be a `h5py.Dataset`, a `h5py.File`, a `h5py.Group`. It also can be a, `silx.gui.hdf5.H5Node` which is needed to display some local path information. |