summaryrefslogtreecommitdiff
path: root/silx/gui/hdf5/Hdf5TreeView.py
diff options
context:
space:
mode:
Diffstat (limited to 'silx/gui/hdf5/Hdf5TreeView.py')
-rw-r--r--silx/gui/hdf5/Hdf5TreeView.py271
1 files changed, 0 insertions, 271 deletions
diff --git a/silx/gui/hdf5/Hdf5TreeView.py b/silx/gui/hdf5/Hdf5TreeView.py
deleted file mode 100644
index a86140a..0000000
--- a/silx/gui/hdf5/Hdf5TreeView.py
+++ /dev/null
@@ -1,271 +0,0 @@
-# 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.
-#
-# ###########################################################################*/
-
-__authors__ = ["V. Valls"]
-__license__ = "MIT"
-__date__ = "30/04/2018"
-
-
-import logging
-from .. import qt
-from ...utils import weakref as silxweakref
-from .Hdf5TreeModel import Hdf5TreeModel
-from .Hdf5HeaderView import Hdf5HeaderView
-from .NexusSortFilterProxyModel import NexusSortFilterProxyModel
-from .Hdf5Item import Hdf5Item
-from . import _utils
-
-_logger = logging.getLogger(__name__)
-
-
-class Hdf5TreeView(qt.QTreeView):
- """TreeView which allow to browse HDF5 file structure.
-
- .. image:: img/Hdf5TreeView.png
-
- It provides columns width auto-resizing and additional
- signals.
-
- The default model is a :class:`NexusSortFilterProxyModel` sourcing
- a :class:`Hdf5TreeModel`. The :class:`Hdf5TreeModel` is reachable using
- :meth:`findHdf5TreeModel`. The default header is :class:`Hdf5HeaderView`.
-
- Context menu is managed by the :meth:`setContextMenuPolicy` with the value
- Qt.CustomContextMenu. This policy must not be changed, otherwise context
- menus will not work anymore. You can use :meth:`addContextMenuCallback` and
- :meth:`removeContextMenuCallback` to add your custum actions according
- to the selected objects.
- """
- def __init__(self, parent=None):
- """
- Constructor
-
- :param parent qt.QWidget: The parent widget
- """
- qt.QTreeView.__init__(self, parent)
-
- model = self.createDefaultModel()
- self.setModel(model)
-
- self.setHeader(Hdf5HeaderView(qt.Qt.Horizontal, self))
- self.setSelectionBehavior(qt.QAbstractItemView.SelectRows)
- self.sortByColumn(0, qt.Qt.AscendingOrder)
- # optimise the rendering
- self.setUniformRowHeights(True)
-
- self.setIconSize(qt.QSize(16, 16))
- self.setAcceptDrops(True)
- self.setDragEnabled(True)
- self.setDragDropMode(qt.QAbstractItemView.DragDrop)
- self.showDropIndicator()
-
- self.__context_menu_callbacks = silxweakref.WeakList()
- self.setContextMenuPolicy(qt.Qt.CustomContextMenu)
- self.customContextMenuRequested.connect(self._createContextMenu)
-
- def createDefaultModel(self):
- """Creates and returns the default model.
-
- Inherite to custom the default model"""
- model = Hdf5TreeModel(self)
- proxy_model = NexusSortFilterProxyModel(self)
- proxy_model.setSourceModel(model)
- return proxy_model
-
- def __removeContextMenuProxies(self, ref):
- """Callback to remove dead proxy from the list"""
- self.__context_menu_callbacks.remove(ref)
-
- def _createContextMenu(self, pos):
- """
- Create context menu.
-
- :param pos qt.QPoint: Position of the context menu
- """
- actions = []
-
- menu = qt.QMenu(self)
-
- hovered_index = self.indexAt(pos)
- hovered_node = self.model().data(hovered_index, Hdf5TreeModel.H5PY_ITEM_ROLE)
- if hovered_node is None or not isinstance(hovered_node, Hdf5Item):
- return
-
- hovered_object = _utils.H5Node(hovered_node)
- event = _utils.Hdf5ContextMenuEvent(self, menu, hovered_object)
-
- for callback in self.__context_menu_callbacks:
- try:
- callback(event)
- except KeyboardInterrupt:
- raise
- except Exception:
- # make sure no user callback crash the application
- _logger.error("Error while calling callback", exc_info=True)
- pass
-
- if not menu.isEmpty():
- for action in actions:
- menu.addAction(action)
- menu.popup(self.viewport().mapToGlobal(pos))
-
- def addContextMenuCallback(self, callback):
- """Register a context menu callback.
-
- The callback will be called when a context menu is requested with the
- treeview and the list of selected h5py objects in parameters. The
- callback must return a list of :class:`qt.QAction` object.
-
- Callbacks are stored as saferef. The object must store a reference by
- itself.
- """
- self.__context_menu_callbacks.append(callback)
-
- def removeContextMenuCallback(self, callback):
- """Unregister a context menu callback"""
- self.__context_menu_callbacks.remove(callback)
-
- def findHdf5TreeModel(self):
- """Find the Hdf5TreeModel from the stack of model filters.
-
- :returns: A Hdf5TreeModel, else None
- :rtype: Hdf5TreeModel
- """
- model = self.model()
- while model is not None:
- if isinstance(model, qt.QAbstractProxyModel):
- model = model.sourceModel()
- else:
- break
- if model is None:
- return None
- if isinstance(model, Hdf5TreeModel):
- return model
- else:
- return None
-
- def dragEnterEvent(self, event):
- model = self.findHdf5TreeModel()
- if model is not None and model.isFileDropEnabled() and event.mimeData().hasFormat("text/uri-list"):
- self.setState(qt.QAbstractItemView.DraggingState)
- event.accept()
- else:
- qt.QTreeView.dragEnterEvent(self, event)
-
- def dragMoveEvent(self, event):
- model = self.findHdf5TreeModel()
- if model is not None and model.isFileDropEnabled() and event.mimeData().hasFormat("text/uri-list"):
- event.setDropAction(qt.Qt.CopyAction)
- event.accept()
- else:
- qt.QTreeView.dragMoveEvent(self, event)
-
- def selectedH5Nodes(self, ignoreBrokenLinks=True):
- """Returns selected h5py objects like :class:`h5py.File`,
- :class:`h5py.Group`, :class:`h5py.Dataset` or mimicked objects.
-
- :param ignoreBrokenLinks bool: Returns objects which are not not
- broken links.
- :rtype: iterator(:class:`_utils.H5Node`)
- """
- for index in self.selectedIndexes():
- if index.column() != 0:
- continue
- item = self.model().data(index, Hdf5TreeModel.H5PY_ITEM_ROLE)
- if item is None:
- continue
- if isinstance(item, Hdf5Item):
- if ignoreBrokenLinks and item.isBrokenObj():
- continue
- yield _utils.H5Node(item)
-
- def __intermediateModels(self, index):
- """Returns intermediate models from the view model to the
- model of the index."""
- models = []
- targetModel = index.model()
- model = self.model()
- while model is not None:
- if model is targetModel:
- # found
- return models
- models.append(model)
- if isinstance(model, qt.QAbstractProxyModel):
- model = model.sourceModel()
- else:
- break
- raise RuntimeError("Model from the requested index is not reachable from this view")
-
- def mapToModel(self, index):
- """Map an index from any model reachable by the view to an index from
- the very first model connected to the view.
-
- :param qt.QModelIndex index: Index from the Hdf5Tree model
- :rtype: qt.QModelIndex
- :return: Index from the model connected to the view
- """
- if not index.isValid():
- return index
- models = self.__intermediateModels(index)
- for model in reversed(models):
- index = model.mapFromSource(index)
- return index
-
- def setSelectedH5Node(self, h5Object):
- """
- Select the specified node of the tree using an h5py node.
-
- - If the item is found, parent items are expended, and then the item
- is selected.
- - If the item is not found, the selection do not change.
- - A none argument allow to deselect everything
-
- :param h5py.Node h5Object: The node to select
- """
- if h5Object is None:
- self.setCurrentIndex(qt.QModelIndex())
- return
-
- model = self.findHdf5TreeModel()
- index = model.indexFromH5Object(h5Object)
- index = self.mapToModel(index)
- if index.isValid():
- # Update the GUI
- i = index
- while i.isValid():
- self.expand(i)
- i = i.parent()
- self.setCurrentIndex(index)
-
- def mousePressEvent(self, event):
- """Override mousePressEvent to provide a consistante compatible API
- between Qt4 and Qt5
- """
- super(Hdf5TreeView, self).mousePressEvent(event)
- if event.button() != qt.Qt.LeftButton:
- # Qt5 only sends itemClicked on left button mouse click
- if qt.qVersion() > "5":
- qindex = self.indexAt(event.pos())
- self.clicked.emit(qindex)