summaryrefslogtreecommitdiff
path: root/silx/gui/data/Hdf5TableView.py
diff options
context:
space:
mode:
Diffstat (limited to 'silx/gui/data/Hdf5TableView.py')
-rw-r--r--silx/gui/data/Hdf5TableView.py62
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.