diff options
Diffstat (limited to 'silx/gui/data/ArrayTableModel.py')
-rw-r--r-- | silx/gui/data/ArrayTableModel.py | 78 |
1 files changed, 68 insertions, 10 deletions
diff --git a/silx/gui/data/ArrayTableModel.py b/silx/gui/data/ArrayTableModel.py index 8805241..b7bd9c4 100644 --- a/silx/gui/data/ArrayTableModel.py +++ b/silx/gui/data/ArrayTableModel.py @@ -1,7 +1,7 @@ # coding: utf-8 # /*########################################################################## # -# Copyright (c) 2016-2019 European Synchrotron Radiation Facility +# Copyright (c) 2016-2021 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 @@ -74,6 +74,10 @@ class ArrayTableModel(qt.QAbstractTableModel): :param sequence[int] perspective: See documentation of :meth:`setPerspective`. """ + + MAX_NUMBER_OF_SECTIONS = 10e6 + """Maximum number of displayed rows and columns""" + def __init__(self, parent=None, data=None, perspective=None): qt.QAbstractTableModel.__init__(self, parent) @@ -173,7 +177,7 @@ class ArrayTableModel(qt.QAbstractTableModel): if row_dim is None: # 0-D and 1-D arrays return 1 - return self._array.shape[row_dim] + return min(self._array.shape[row_dim], self.MAX_NUMBER_OF_SECTIONS) def columnCount(self, parent_idx=None): """QAbstractTableModel method @@ -182,14 +186,55 @@ class ArrayTableModel(qt.QAbstractTableModel): if col_dim is None: # 0-D array return 1 - return self._array.shape[col_dim] + return min(self._array.shape[col_dim], self.MAX_NUMBER_OF_SECTIONS) + + def __isClipped(self, orientation=qt.Qt.Vertical) -> bool: + """Returns whether or not array is clipped in a given orientation""" + if orientation == qt.Qt.Vertical: + dim = self._getRowDim() + else: + dim = self._getColumnDim() + return (dim is not None and + self._array.shape[dim] > self.MAX_NUMBER_OF_SECTIONS) + + def __isClippedIndex(self, index) -> bool: + """Returns whether or not index's cell represents clipped data.""" + if not index.isValid(): + return False + if index.row() == self.MAX_NUMBER_OF_SECTIONS - 2: + return self.__isClipped(qt.Qt.Vertical) + if index.column() == self.MAX_NUMBER_OF_SECTIONS - 2: + return self.__isClipped(qt.Qt.Horizontal) + return False + + def __clippedData(self, role=qt.Qt.DisplayRole): + """Return data for cells representing clipped data""" + if role == qt.Qt.DisplayRole: + return "..." + elif role == qt.Qt.ToolTipRole: + return "Dataset is too large: display is clipped" + else: + return None def data(self, index, role=qt.Qt.DisplayRole): """QAbstractTableModel method to access data values in the format ready to be displayed""" if index.isValid(): - selection = self._getIndexTuple(index.row(), - index.column()) + if self.__isClippedIndex(index): # Special displayed for clipped data + return self.__clippedData(role) + + row, column = index.row(), index.column() + + # When clipped, display last data of the array in last column of the table + if (self.__isClipped(qt.Qt.Vertical) and + row == self.MAX_NUMBER_OF_SECTIONS - 1): + row = self._array.shape[self._getRowDim()] - 1 + if (self.__isClipped(qt.Qt.Horizontal) and + column == self.MAX_NUMBER_OF_SECTIONS - 1): + column = self._array.shape[self._getColumnDim()] - 1 + + selection = self._getIndexTuple(row, column) + if role == qt.Qt.DisplayRole: return self._formatter.toString(self._array[selection], self._array.dtype) @@ -224,17 +269,30 @@ class ArrayTableModel(qt.QAbstractTableModel): """QAbstractTableModel method Return the 0-based row or column index, for display in the horizontal and vertical headers""" + if self.__isClipped(orientation): # Header is clipped + if section == self.MAX_NUMBER_OF_SECTIONS - 2: + # Represent clipped data + return self.__clippedData(role) + + elif section == self.MAX_NUMBER_OF_SECTIONS - 1: + # Display last index from data not table + if role == qt.Qt.DisplayRole: + if orientation == qt.Qt.Vertical: + dim = self._getRowDim() + else: + dim = self._getColumnDim() + return str(self._array.shape[dim] - 1) + else: + return None + if role == qt.Qt.DisplayRole: - if orientation == qt.Qt.Vertical: - return "%d" % section - if orientation == qt.Qt.Horizontal: - return "%d" % section + return "%d" % section return None def flags(self, index): """QAbstractTableModel method to inform the view whether data is editable or not.""" - if not self._editable: + if not self._editable or self.__isClippedIndex(index): return qt.QAbstractTableModel.flags(self, index) return qt.QAbstractTableModel.flags(self, index) | qt.Qt.ItemIsEditable |