diff --git a/Orange/widgets/data/owselectcolumns.py b/Orange/widgets/data/owselectcolumns.py index 9e673d25719..8b54eaf3ef9 100644 --- a/Orange/widgets/data/owselectcolumns.py +++ b/Orange/widgets/data/owselectcolumns.py @@ -5,7 +5,7 @@ from AnyQt.QtWidgets import QListView from AnyQt.QtCore import ( Qt, QTimer, QSortFilterProxyModel, QItemSelection, QItemSelectionModel, - QMimeData + QMimeData, QAbstractItemModel ) from Orange.widgets import gui, widget @@ -411,12 +411,20 @@ def selected_rows(view): rows = [model.mapToSource(r) for r in rows] return [r.row() for r in rows] - def move_rows(self, view, rows, offset): - model = view.model() - newrows = [min(max(0, row + offset), len(model) - 1) for row in rows] + def move_rows(self, view: QListView, offset: int, roles=(Qt.EditRole,)): + rows = [idx.row() for idx in view.selectionModel().selectedRows()] + model = view.model() # type: QAbstractItemModel + rowcount = model.rowCount() + newrows = [min(max(0, row + offset), rowcount - 1) for row in rows] + + def itemData(index): + return {role: model.data(index, role) for role in roles} for row, newrow in sorted(zip(rows, newrows), reverse=offset > 0): - model[row], model[newrow] = model[newrow], model[row] + d1 = itemData(model.index(row, 0)) + d2 = itemData(model.index(newrow, 0)) + model.setItemData(model.index(row, 0), d2) + model.setItemData(model.index(newrow, 0), d1) selection = QItemSelection() for nrow in newrows: @@ -427,13 +435,11 @@ def move_rows(self, view, rows, offset): self.commit() - def move_up(self, view): - selected = self.selected_rows(view) - self.move_rows(view, selected, -1) + def move_up(self, view: QListView): + self.move_rows(view, -1) - def move_down(self, view): - selected = self.selected_rows(view) - self.move_rows(view, selected, 1) + def move_down(self, view: QListView): + self.move_rows(view, 1) def move_selected(self, view): if self.selected_rows(view): diff --git a/Orange/widgets/data/tests/test_owselectcolumns.py b/Orange/widgets/data/tests/test_owselectcolumns.py index 718678035ed..d9d6aed277c 100644 --- a/Orange/widgets/data/tests/test_owselectcolumns.py +++ b/Orange/widgets/data/tests/test_owselectcolumns.py @@ -363,3 +363,26 @@ def _drag_enter_event(self, variables): mime.setProperty("_items", variables) return QDragEnterEvent(QPoint(0, 0), Qt.MoveAction, mime, Qt.NoButton, Qt.NoModifier) + + def test_move_rows(self): + data = Table("iris")[:5] + w = self.widget + self.send_signal(w.Inputs.data, data) + view = w.used_attrs_view + model = view.model() + selmodel = view.selectionModel() + midx = model.index(1, 0) + selmodel.select(midx, selmodel.ClearAndSelect) + + w.move_up(view) + d1 = self.get_output(w.Outputs.data, w) + self.assertEqual( + d1.domain.attributes, + data.domain.attributes[:2][::-1] + data.domain.attributes[2:] + ) + w.move_down(view) + d1 = self.get_output(w.Outputs.data, w) + self.assertEqual( + d1.domain.attributes, + data.domain.attributes + )