diff options
Diffstat (limited to 'silx/gui/hdf5/Hdf5HeaderView.py')
-rw-r--r-- | silx/gui/hdf5/Hdf5HeaderView.py | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/silx/gui/hdf5/Hdf5HeaderView.py b/silx/gui/hdf5/Hdf5HeaderView.py new file mode 100644 index 0000000..5912230 --- /dev/null +++ b/silx/gui/hdf5/Hdf5HeaderView.py @@ -0,0 +1,192 @@ +# coding: utf-8 +# /*########################################################################## +# +# Copyright (c) 2016 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__ = "08/11/2016" + + +from .. import qt + +QTVERSION = qt.qVersion() + + +class Hdf5HeaderView(qt.QHeaderView): + """ + Default HDF5 header + + Manage auto-resize and context menu to display/hide columns + """ + + def __init__(self, orientation, parent=None): + """ + Constructor + + :param orientation qt.Qt.Orientation: Orientation of the header + :param parent qt.QWidget: Parent of the widget + """ + super(Hdf5HeaderView, self).__init__(orientation, parent) + self.setContextMenuPolicy(qt.Qt.CustomContextMenu) + self.customContextMenuRequested.connect(self.__createContextMenu) + + # default initialization done by QTreeView for it's own header + if QTVERSION < "5.0": + self.setClickable(True) + self.setMovable(True) + else: + self.setSectionsClickable(True) + self.setSectionsMovable(True) + self.setDefaultAlignment(qt.Qt.AlignLeft | qt.Qt.AlignVCenter) + self.setStretchLastSection(True) + + self.__auto_resize = True + self.__hide_columns_popup = True + + def setModel(self, model): + """Override model to configure view when a model is expected + + `qt.QHeaderView.setResizeMode` expect already existing columns + to work. + + :param model qt.QAbstractItemModel: A model + """ + super(Hdf5HeaderView, self).setModel(model) + self.__updateAutoResize() + + def __updateAutoResize(self): + """Update the view according to the state of the auto-resize""" + if QTVERSION < "5.0": + setResizeMode = self.setResizeMode + else: + setResizeMode = self.setSectionResizeMode + + if self.__auto_resize: + setResizeMode(0, qt.QHeaderView.ResizeToContents) + setResizeMode(1, qt.QHeaderView.ResizeToContents) + setResizeMode(2, qt.QHeaderView.ResizeToContents) + setResizeMode(3, qt.QHeaderView.Interactive) + setResizeMode(4, qt.QHeaderView.Interactive) + setResizeMode(5, qt.QHeaderView.ResizeToContents) + else: + setResizeMode(0, qt.QHeaderView.Interactive) + setResizeMode(1, qt.QHeaderView.Interactive) + setResizeMode(2, qt.QHeaderView.Interactive) + setResizeMode(3, qt.QHeaderView.Interactive) + setResizeMode(4, qt.QHeaderView.Interactive) + setResizeMode(5, qt.QHeaderView.Interactive) + + def setAutoResizeColumns(self, autoResize): + """Enable/disable auto-resize. When auto-resized, the header take care + of the content of the column to set fixed size of some of them, or to + auto fix the size according to the content. + + :param autoResize bool: Enable/disable auto-resize + """ + if self.__auto_resize == autoResize: + return + self.__auto_resize = autoResize + self.__updateAutoResize() + + def hasAutoResizeColumns(self): + """Is auto-resize enabled. + + :rtype: bool + """ + return self.__auto_resize + + autoResizeColumns = qt.Property(bool, hasAutoResizeColumns, setAutoResizeColumns) + """Property to enable/disable auto-resize.""" + + def setEnableHideColumnsPopup(self, enablePopup): + """Enable/disable a popup to allow to hide/show each column of the + model. + + :param bool enablePopup: Enable/disable popup to hide/show columns + """ + self.__hide_columns_popup = enablePopup + + def hasHideColumnsPopup(self): + """Is popup to hide/show columns is enabled. + + :rtype: bool + """ + return self.__hide_columns_popup + + enableHideColumnsPopup = qt.Property(bool, hasHideColumnsPopup, setAutoResizeColumns) + """Property to enable/disable popup allowing to hide/show columns.""" + + def __genHideSectionEvent(self, column): + """Generate a callback which change the column visibility according to + the event parameter + + :param int column: logical id of the column + :rtype: callable + """ + return lambda checked: self.setSectionHidden(column, not checked) + + def __createContextMenu(self, pos): + """Callback to create and display a context menu + + :param pos qt.QPoint: Requested position for the context menu + """ + if not self.__hide_columns_popup: + return + + model = self.model() + if model.columnCount() > 1: + menu = qt.QMenu(self) + menu.setTitle("Display/hide columns") + + action = qt.QAction("Display/hide column", self) + action.setEnabled(False) + menu.addAction(action) + + for column in range(model.columnCount()): + if column == 0: + # skip the main column + continue + text = model.headerData(column, qt.Qt.Horizontal, qt.Qt.DisplayRole) + action = qt.QAction("%s displayed" % text, self) + action.setCheckable(True) + action.setChecked(not self.isSectionHidden(column)) + action.toggled.connect(self.__genHideSectionEvent(column)) + menu.addAction(action) + + menu.popup(self.viewport().mapToGlobal(pos)) + + def setSections(self, logicalIndexes): + """ + Defines order of visible sections by logical indexes. + + Use `Hdf5TreeModel.NAME_COLUMN` to set the list. + + :param list logicalIndexes: List of logical indexes to display + """ + for pos, column_id in enumerate(logicalIndexes): + current_pos = self.visualIndex(column_id) + self.moveSection(current_pos, pos) + self.setSectionHidden(column_id, False) + for column_id in set(range(self.model().columnCount())) - set(logicalIndexes): + self.setSectionHidden(column_id, True) |