summaryrefslogtreecommitdiff
path: root/silx/gui/hdf5/_utils.py
diff options
context:
space:
mode:
authorPicca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>2017-08-18 14:48:52 +0200
committerPicca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>2017-08-18 14:48:52 +0200
commitf7bdc2acff3c13a6d632c28c4569690ab106eed7 (patch)
tree9d67cdb7152ee4e711379e03fe0546c7c3b97303 /silx/gui/hdf5/_utils.py
Import Upstream version 0.5.0+dfsg
Diffstat (limited to 'silx/gui/hdf5/_utils.py')
-rw-r--r--silx/gui/hdf5/_utils.py247
1 files changed, 247 insertions, 0 deletions
diff --git a/silx/gui/hdf5/_utils.py b/silx/gui/hdf5/_utils.py
new file mode 100644
index 0000000..af9c79f
--- /dev/null
+++ b/silx/gui/hdf5/_utils.py
@@ -0,0 +1,247 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
+"""This package provides a set of helper class and function used by the
+package `silx.gui.hdf5` package.
+"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "26/04/2017"
+
+
+import logging
+import numpy
+from .. import qt
+import silx.io.utils
+from silx.utils.html import escape
+
+_logger = logging.getLogger(__name__)
+
+try:
+ import h5py
+except ImportError as e:
+ _logger.error("Module %s requires h5py", __name__)
+ raise e
+
+
+class Hdf5ContextMenuEvent(object):
+ """Hold information provided to context menu callbacks."""
+
+ def __init__(self, source, menu, hoveredObject):
+ """
+ Constructor
+
+ :param QWidget source: Widget source
+ :param QMenu menu: Context menu which will be displayed
+ :param H5Node hoveredObject: Hovered H5 node
+ """
+ self.__source = source
+ self.__menu = menu
+ self.__hoveredObject = hoveredObject
+
+ def source(self):
+ """Source of the event
+
+ :rtype: Hdf5TreeView
+ """
+ return self.__source
+
+ def menu(self):
+ """Menu which will be displayed
+
+ :rtype: qt.QMenu
+ """
+ return self.__menu
+
+ def hoveredObject(self):
+ """Item content hovered by the mouse when the context menu was
+ requested
+
+ :rtype: H5Node
+ """
+ return self.__hoveredObject
+
+
+def htmlFromDict(dictionary, title=None):
+ """Generate a readable HTML from a dictionary
+
+ :param dict dictionary: A Dictionary
+ :rtype: str
+ """
+ result = """<html>
+ <head>
+ <style type="text/css">
+ ul { -qt-list-indent: 0; list-style: none; }
+ li > b {display: inline-block; min-width: 4em; font-weight: bold; }
+ </style>
+ </head>
+ <body>
+ """
+ if title is not None:
+ result += "<b>%s</b>" % escape(title)
+ result += "<ul>"
+ for key, value in dictionary.items():
+ result += "<li><b>%s</b>: %s</li>" % (escape(key), escape(value))
+ result += "</ul>"
+ result += "</body></html>"
+ return result
+
+
+class Hdf5NodeMimeData(qt.QMimeData):
+ """Mimedata class to identify an internal drag and drop of a Hdf5Node."""
+
+ MIME_TYPE = "application/x-internal-h5py-node"
+
+ def __init__(self, node=None):
+ qt.QMimeData.__init__(self)
+ self.__node = node
+ self.setData(self.MIME_TYPE, "".encode(encoding='utf-8'))
+
+ def node(self):
+ return self.__node
+
+
+class H5Node(object):
+ """Adapter over an h5py object to provide missing informations from h5py
+ nodes, like internal node path and filename (which are not provided by
+ :mod:`h5py` for soft and external links).
+
+ It also provides an abstraction to reach node type for mimicked h5py
+ objects.
+ """
+
+ def __init__(self, h5py_item=None):
+ """Constructor
+
+ :param Hdf5Item h5py_item: An Hdf5Item
+ """
+ self.__h5py_object = h5py_item.obj
+ self.__h5py_item = h5py_item
+
+ def __getattr__(self, name):
+ return object.__getattribute__(self.__h5py_object, name)
+
+ @property
+ def h5py_object(self):
+ """Returns the internal h5py node.
+
+ :rtype: h5py.File or h5py.Group or h5py.Dataset
+ """
+ return self.__h5py_object
+
+ @property
+ def ntype(self):
+ """Returns the node type, as an h5py class.
+
+ :rtype:
+ :class:`h5py.File`, :class:`h5py.Group` or :class:`h5py.Dataset`
+ """
+ return silx.io.utils.get_h5py_class(self.__h5py_object)
+
+ @property
+ def basename(self):
+ """Returns the basename of this h5py node. It is the last identifier of
+ the path.
+
+ :rtype: str
+ """
+ return self.__h5py_object.name.split("/")[-1]
+
+ @property
+ def local_name(self):
+ """Returns the local path of this h5py node.
+
+ For links, this path is not equal to the h5py one.
+
+ :rtype: str
+ """
+ if self.__h5py_item is None:
+ raise RuntimeError("h5py_item is not defined")
+
+ result = []
+ item = self.__h5py_item
+ while item is not None:
+ if issubclass(item.h5pyClass, h5py.File):
+ break
+ result.append(item.basename)
+ item = item.parent
+ if item is None:
+ raise RuntimeError("The item does not have parent holding h5py.File")
+ if result == []:
+ return "/"
+ result.append("")
+ result.reverse()
+ return "/".join(result)
+
+ def __file_item(self):
+ """Returns the parent item holding the :class:`h5py.File` object
+
+ :rtype: h5py.File
+ :raises RuntimeException: If no file are found
+ """
+ item = self.__h5py_item
+ while item is not None:
+ if issubclass(item.h5pyClass, h5py.File):
+ return item
+ item = item.parent
+ raise RuntimeError("The item does not have parent holding h5py.File")
+
+ @property
+ def local_file(self):
+ """Returns the local :class:`h5py.File` object.
+
+ For path containing external links, this file is not equal to the h5py
+ one.
+
+ :rtype: h5py.File
+ :raises RuntimeException: If no file are found
+ """
+ item = self.__file_item()
+ return item.obj
+
+ @property
+ def local_filename(self):
+ """Returns the local filename of the h5py node.
+
+ For path containing external links, this path is not equal to the
+ filename provided by h5py.
+
+ :rtype: str
+ :raises RuntimeException: If no file are found
+ """
+ return self.local_file.filename
+
+ @property
+ def local_basename(self):
+ """Returns the local filename of the h5py node.
+
+ For path containing links, this basename can be different than the
+ basename provided by h5py.
+
+ :rtype: str
+ """
+ if issubclass(self.__h5py_item.h5pyClass, h5py.File):
+ return ""
+ return self.__h5py_item.basename