diff --git a/spyderlib/widgets/varexp/arrayeditor.py b/spyderlib/widgets/varexp/arrayeditor.py index 4177e7738f8..581e61a88d2 100644 --- a/spyderlib/widgets/varexp/arrayeditor.py +++ b/spyderlib/widgets/varexp/arrayeditor.py @@ -21,7 +21,8 @@ QMessageBox, QPushButton, QInputDialog, QMenu, QApplication, QKeySequence, QLabel, QComboBox, QSpinBox, QStackedWidget, QWidget, QVBoxLayout, - QAbstractItemDelegate) + QAbstractItemDelegate, QItemSelection, + QItemSelectionRange) from spyderlib.qt.QtCore import (Qt, QModelIndex, QAbstractTableModel, Slot) from spyderlib.qt.compat import to_qvariant, from_qvariant @@ -403,10 +404,39 @@ def __init__(self, parent, model, dtype, shape): lambda val: self.load_more_data(val, rows=True)) def load_more_data(self, value, rows=False, columns=False): + old_selection = self.selectionModel().selection() + old_rows_loaded = old_cols_loaded = None + if rows and value == self.verticalScrollBar().maximum(): + old_rows_loaded = self.model().rows_loaded self.model().fetch_more(rows=rows) + if columns and value == self.horizontalScrollBar().maximum(): + old_cols_loaded = self.model().cols_loaded self.model().fetch_more(columns=columns) + + if old_rows_loaded is not None or old_cols_loaded is not None: + # if we've changed anything, update selection + new_selection = QItemSelection() + for part in old_selection: + top = part.top() + bottom = part.bottom() + if (old_rows_loaded is not None and + top == 0 and bottom == (old_rows_loaded-1)): + # complete column selected (so expand it to match updated range) + bottom = self.model().rows_loaded-1 + left = part.left() + right = part.right() + if (old_cols_loaded is not None + and left == 0 and right == (old_cols_loaded-1)): + # compete row selected (so expand it to match updated range) + right = self.model().cols_loaded-1 + top_left = self.model().index(top, left) + bottom_right = self.model().index(bottom, right) + part = QItemSelectionRange(top_left, bottom_right) + new_selection.append(part) + self.selectionModel().select(new_selection, self.selectionModel().ClearAndSelect) + def resize_to_contents(self): """Resize cells to contents""" @@ -444,6 +474,14 @@ def _sel_to_text(self, cell_range): if not cell_range: return row_min, row_max, col_min, col_max = get_idx_rect(cell_range) + if col_min == 0 and col_max == (self.model().cols_loaded-1): + # we've selected a whole column. It isn't possible to + # select only the first part of a column without loading more, + # so we can treat it as intentional and copy the whole thing + col_max = self.model().total_cols-1 + if row_min == 0 and row_max == (self.model().rows_loaded-1): + row_max = self.model().total_rows-1 + _data = self.model().get_data() if PY3: output = io.BytesIO()