diff options
author | Dirk Fauth | 2018-11-02 17:29:49 +0000 |
---|---|---|
committer | Dirk Fauth | 2018-11-02 17:29:49 +0000 |
commit | 9ca5b2a680c4282c93fb5b3e295e0987122cfb53 (patch) | |
tree | 2295061c96dceb542758fa2d9ccf24e561b4895d | |
parent | b383162a4e6df63081c43f39b72619af25ca1930 (diff) | |
download | org.eclipse.nebula.widgets.nattable-9ca5b2a680c4282c93fb5b3e295e0987122cfb53.tar.gz org.eclipse.nebula.widgets.nattable-9ca5b2a680c4282c93fb5b3e295e0987122cfb53.tar.xz org.eclipse.nebula.widgets.nattable-9ca5b2a680c4282c93fb5b3e295e0987122cfb53.zip |
Bug 540732 - Selection movement not working always with custom
ITraversalStrategy
Change-Id: I635773e4fa36fdf08b5f8a8649e65beda1700874
Signed-off-by: Dirk Fauth <dirk.fauth@googlemail.com>
4 files changed, 436 insertions, 45 deletions
diff --git a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/selection/CellSelectionTraversalTest.java b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/selection/CellSelectionTraversalTest.java index 76f18bd8..737c48e5 100644 --- a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/selection/CellSelectionTraversalTest.java +++ b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/selection/CellSelectionTraversalTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014 Dirk Fauth. + * Copyright (c) 2014, 2018 Dirk Fauth. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,6 +12,7 @@ package org.eclipse.nebula.widgets.nattable.selection; import static org.junit.Assert.assertEquals; +import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell; import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer.MoveDirectionEnum; import org.eclipse.nebula.widgets.nattable.selection.command.MoveSelectionCommand; import org.eclipse.nebula.widgets.nattable.test.fixture.layer.DataLayerFixture; @@ -1660,4 +1661,266 @@ public class CellSelectionTraversalTest { assertEquals(8, this.selectionLayer.getLastSelectedCell().getRowPosition()); } + @Test + public void testMoveToRowEndWithCustomStrategy() { + this.viewportLayer.registerCommandHandler( + new MoveCellSelectionCommandHandler(this.selectionLayer, new ITraversalStrategy() { + + @Override + public TraversalScope getTraversalScope() { + return TraversalScope.TABLE; + } + + @Override + public boolean isCycle() { + return true; + } + + @Override + public int getStepCount() { + return 1; + } + + @Override + public boolean isValidTarget(ILayerCell from, ILayerCell to) { + if (to.getColumnIndex() == 0 || to.getColumnIndex() == 9) { + return false; + } + return true; + } + + })); + + // select a cell + this.selectionLayer.setSelectedCell(1, 2); + assertEquals(1, this.selectionLayer.getLastSelectedCell().getColumnPosition()); + assertEquals(2, this.selectionLayer.getLastSelectedCell().getRowPosition()); + + // move to end + this.viewportLayer.doCommand(new MoveSelectionCommand( + MoveDirectionEnum.RIGHT, + SelectionLayer.MOVE_ALL, + false, + false)); + + assertEquals(8, this.selectionLayer.getLastSelectedCell().getColumnPosition()); + assertEquals(2, this.selectionLayer.getLastSelectedCell().getRowPosition()); + } + + @Test + public void testMoveToRowStartWithCustomStrategy() { + this.viewportLayer.registerCommandHandler( + new MoveCellSelectionCommandHandler(this.selectionLayer, new ITraversalStrategy() { + + @Override + public TraversalScope getTraversalScope() { + return TraversalScope.TABLE; + } + + @Override + public boolean isCycle() { + return true; + } + + @Override + public int getStepCount() { + return 1; + } + + @Override + public boolean isValidTarget(ILayerCell from, ILayerCell to) { + if (to.getColumnIndex() == 0 || to.getColumnIndex() == 9) { + return false; + } + return true; + } + + })); + + // select a cell + this.selectionLayer.setSelectedCell(7, 2); + assertEquals(7, this.selectionLayer.getLastSelectedCell().getColumnPosition()); + assertEquals(2, this.selectionLayer.getLastSelectedCell().getRowPosition()); + + // move to start + this.viewportLayer.doCommand(new MoveSelectionCommand( + MoveDirectionEnum.LEFT, + SelectionLayer.MOVE_ALL, + false, + false)); + + assertEquals(1, this.selectionLayer.getLastSelectedCell().getColumnPosition()); + assertEquals(2, this.selectionLayer.getLastSelectedCell().getRowPosition()); + } + + @Test + public void testMoveToTableEndWithCustomStrategy() { + this.viewportLayer.registerCommandHandler( + new MoveCellSelectionCommandHandler(this.selectionLayer, new ITraversalStrategy() { + + @Override + public TraversalScope getTraversalScope() { + return TraversalScope.TABLE; + } + + @Override + public boolean isCycle() { + return true; + } + + @Override + public int getStepCount() { + return 1; + } + + @Override + public boolean isValidTarget(ILayerCell from, ILayerCell to) { + if (to.getColumnIndex() == 0 || to.getColumnIndex() == 9) { + return false; + } + return true; + } + + })); + + // select a cell + this.selectionLayer.setSelectedCell(4, 4); + assertEquals(4, this.selectionLayer.getLastSelectedCell().getColumnPosition()); + assertEquals(4, this.selectionLayer.getLastSelectedCell().getRowPosition()); + + // move to end + this.viewportLayer.doCommand(new MoveSelectionCommand( + MoveDirectionEnum.RIGHT, + SelectionLayer.MOVE_ALL, + false, + false)); + this.viewportLayer.doCommand(new MoveSelectionCommand( + MoveDirectionEnum.DOWN, + SelectionLayer.MOVE_ALL, + false, + false)); + + assertEquals(8, this.selectionLayer.getLastSelectedCell().getColumnPosition()); + assertEquals(9, this.selectionLayer.getLastSelectedCell().getRowPosition()); + } + + @Test + public void testMoveToTableStartWithCustomStrategy() { + this.viewportLayer.registerCommandHandler( + new MoveCellSelectionCommandHandler(this.selectionLayer, new ITraversalStrategy() { + + @Override + public TraversalScope getTraversalScope() { + return TraversalScope.TABLE; + } + + @Override + public boolean isCycle() { + return true; + } + + @Override + public int getStepCount() { + return 1; + } + + @Override + public boolean isValidTarget(ILayerCell from, ILayerCell to) { + if (to.getColumnIndex() == 0 || to.getColumnIndex() == 9) { + return false; + } + return true; + } + + })); + + // select a cell + this.selectionLayer.setSelectedCell(4, 4); + assertEquals(4, this.selectionLayer.getLastSelectedCell().getColumnPosition()); + assertEquals(4, this.selectionLayer.getLastSelectedCell().getRowPosition()); + + // move to start + this.viewportLayer.doCommand(new MoveSelectionCommand( + MoveDirectionEnum.LEFT, + SelectionLayer.MOVE_ALL, + false, + true)); + this.viewportLayer.doCommand(new MoveSelectionCommand( + MoveDirectionEnum.UP, + SelectionLayer.MOVE_ALL, + false, + false)); + + assertEquals(1, this.selectionLayer.getLastSelectedCell().getColumnPosition()); + assertEquals(0, this.selectionLayer.getLastSelectedCell().getRowPosition()); + } + + @Test + public void testMoveToTableStartEndWithCustomStrategy() { + this.viewportLayer.registerCommandHandler( + new MoveCellSelectionCommandHandler(this.selectionLayer, new ITraversalStrategy() { + + @Override + public TraversalScope getTraversalScope() { + return TraversalScope.TABLE; + } + + @Override + public boolean isCycle() { + return true; + } + + @Override + public int getStepCount() { + return 1; + } + + @Override + public boolean isValidTarget(ILayerCell from, ILayerCell to) { + // first and last column and first and last row are not + // valid + if (to.getColumnIndex() == 0 || to.getColumnIndex() == 9 + || to.getRowIndex() == 0 || to.getRowIndex() == 9) { + return false; + } + return true; + } + + })); + + // select a cell + this.selectionLayer.setSelectedCell(4, 4); + assertEquals(4, this.selectionLayer.getLastSelectedCell().getColumnPosition()); + assertEquals(4, this.selectionLayer.getLastSelectedCell().getRowPosition()); + + // move to start + this.viewportLayer.doCommand(new MoveSelectionCommand( + MoveDirectionEnum.LEFT, + SelectionLayer.MOVE_ALL, + false, + true)); + this.viewportLayer.doCommand(new MoveSelectionCommand( + MoveDirectionEnum.UP, + SelectionLayer.MOVE_ALL, + false, + false)); + + assertEquals(1, this.selectionLayer.getLastSelectedCell().getColumnPosition()); + assertEquals(1, this.selectionLayer.getLastSelectedCell().getRowPosition()); + + // move to end + this.viewportLayer.doCommand(new MoveSelectionCommand( + MoveDirectionEnum.RIGHT, + SelectionLayer.MOVE_ALL, + false, + false)); + this.viewportLayer.doCommand(new MoveSelectionCommand( + MoveDirectionEnum.DOWN, + SelectionLayer.MOVE_ALL, + false, + false)); + + assertEquals(8, this.selectionLayer.getLastSelectedCell().getColumnPosition()); + assertEquals(8, this.selectionLayer.getLastSelectedCell().getRowPosition()); + } } diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/EditTraversalStrategy.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/EditTraversalStrategy.java index 19031898..fe6329ce 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/EditTraversalStrategy.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/EditTraversalStrategy.java @@ -41,7 +41,7 @@ public class EditTraversalStrategy implements ITraversalStrategy { /** * * @param baseStrategy - * The {@link ITraversalStrategy} that shoud be wrapped by this + * The {@link ITraversalStrategy} that should be wrapped by this * {@link EditTraversalStrategy}. * @param natTable * The NatTable instance this strategy is connected to. Needed to diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/MoveCellSelectionCommandHandler.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/MoveCellSelectionCommandHandler.java index 34998731..2b80b10c 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/MoveCellSelectionCommandHandler.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/MoveCellSelectionCommandHandler.java @@ -139,21 +139,51 @@ public class MoveCellSelectionCommandHandler extends MoveSelectionCommandHandler if (!traversalStrategy.isValidTarget(lastSelectedCell, this.selectionLayer.getCellByPosition(this.newSelectedColumnPosition, this.newSelectedRowPosition))) { - if (!stopTraversalOnInvalid) { - moveLastSelectedLeft( - createIncrementalStrategy(traversalStrategy), - withShiftMask, withControlMask); + // for MOVE_ALL we need to go backwards to find the last + // valid position + if (stepSize == SelectionLayer.MOVE_ALL) { + for (int i = this.newSelectedColumnPosition; i < this.selectionLayer.getColumnCount(); i++) { + ILayerCell newPosition = this.selectionLayer.getCellByPosition(i, this.newSelectedRowPosition); + if (traversalStrategy.isValidTarget(lastSelectedCell, newPosition)) { + this.newSelectedColumnPosition = i; + + if (!withShiftMask) { + this.selectionLayer.clear(false); + } + + this.selectionLayer.selectCell( + this.newSelectedColumnPosition, + this.newSelectedRowPosition, + withShiftMask, + withControlMask); + this.selectionLayer.fireCellSelectionEvent( + this.newSelectedColumnPosition, + this.newSelectedRowPosition, + true, + withShiftMask, + withControlMask); + + break; + } + } } else { - // since the calculated target is invalid and - // invalid traversal movement should stop, the new - // selected position is the last valid one - this.newSelectedColumnPosition = this.lastSelectedCellPosition.columnPosition; - this.newSelectedRowPosition = this.lastSelectedCellPosition.rowPosition; + if (!stopTraversalOnInvalid) { + moveLastSelectedLeft( + createIncrementalStrategy(traversalStrategy), + withShiftMask, withControlMask); + } else { + // since the calculated target is invalid and + // invalid traversal movement should stop, the + // new selected position is the last valid one + this.newSelectedColumnPosition = this.lastSelectedCellPosition.columnPosition; + this.newSelectedRowPosition = this.lastSelectedCellPosition.rowPosition; + } } } else { if (stepSize == SelectionLayer.MOVE_ALL && !withShiftMask) { this.selectionLayer.clear(false); } + this.selectionLayer.selectCell( this.newSelectedColumnPosition, this.newSelectedRowPosition, @@ -190,7 +220,8 @@ public class MoveCellSelectionCommandHandler extends MoveSelectionCommandHandler this.newSelectedColumnPosition, this.newSelectedRowPosition); if (newSelected != null) { - // if cell has column spanning, ensure that the whole cell is displayed + // if cell has column spanning, ensure that the whole cell + // is displayed this.newSelectedColumnPosition = newSelected.getOriginColumnPosition() + newSelected.getColumnSpan() - 1; } @@ -235,27 +266,56 @@ public class MoveCellSelectionCommandHandler extends MoveSelectionCommandHandler } if (positionMoved()) { - if (stepSize == SelectionLayer.MOVE_ALL && !withShiftMask) { - this.selectionLayer.clear(false); - } - // check if calculated target is valid, otherwise move to // adjacent if (!traversalStrategy.isValidTarget(lastSelectedCell, this.selectionLayer.getCellByPosition(this.newSelectedColumnPosition, this.newSelectedRowPosition))) { - if (!stopTraversalOnInvalid) { - moveLastSelectedRight( - createIncrementalStrategy(traversalStrategy), - withShiftMask, withControlMask); + // for MOVE_ALL we need to go backwards to find the last + // valid position + if (stepSize == SelectionLayer.MOVE_ALL) { + for (int i = this.newSelectedColumnPosition; i >= 0; i--) { + ILayerCell newPosition = this.selectionLayer.getCellByPosition(i, this.newSelectedRowPosition); + if (traversalStrategy.isValidTarget(lastSelectedCell, newPosition)) { + this.newSelectedColumnPosition = i; + + if (!withShiftMask) { + this.selectionLayer.clear(false); + } + + this.selectionLayer.selectCell( + this.newSelectedColumnPosition, + this.newSelectedRowPosition, + withShiftMask, + withControlMask); + this.selectionLayer.fireCellSelectionEvent( + this.newSelectedColumnPosition, + this.newSelectedRowPosition, + true, + withShiftMask, + withControlMask); + + break; + } + } } else { - // since the calculated target is invalid and - // invalid traversal movement should stop, the new - // selected position is the last valid one - this.newSelectedColumnPosition = this.lastSelectedCellPosition.columnPosition; - this.newSelectedRowPosition = this.lastSelectedCellPosition.rowPosition; + if (!stopTraversalOnInvalid) { + moveLastSelectedRight( + createIncrementalStrategy(traversalStrategy), + withShiftMask, withControlMask); + } else { + // since the calculated target is invalid and + // invalid traversal movement should stop, the + // new selected position is the last valid one + this.newSelectedColumnPosition = this.lastSelectedCellPosition.columnPosition; + this.newSelectedRowPosition = this.lastSelectedCellPosition.rowPosition; + } } } else { + if (stepSize == SelectionLayer.MOVE_ALL && !withShiftMask) { + this.selectionLayer.clear(false); + } + this.selectionLayer.selectCell( this.newSelectedColumnPosition, this.newSelectedRowPosition, @@ -338,18 +398,51 @@ public class MoveCellSelectionCommandHandler extends MoveSelectionCommandHandler if (!traversalStrategy.isValidTarget(lastSelectedCell, this.selectionLayer.getCellByPosition(this.newSelectedColumnPosition, this.newSelectedRowPosition))) { - if (!stopTraversalOnInvalid) { - moveLastSelectedUp( - createIncrementalStrategy(traversalStrategy), - withShiftMask, withControlMask); + // for MOVE_ALL we need to go backwards to find the last + // valid position + if (stepSize == SelectionLayer.MOVE_ALL) { + for (int i = this.newSelectedRowPosition; i < this.selectionLayer.getRowCount(); i++) { + ILayerCell newPosition = this.selectionLayer.getCellByPosition(this.newSelectedColumnPosition, i); + if (traversalStrategy.isValidTarget(lastSelectedCell, newPosition)) { + this.newSelectedRowPosition = i; + + if (!withShiftMask) { + this.selectionLayer.clear(false); + } + + this.selectionLayer.selectCell( + this.newSelectedColumnPosition, + this.newSelectedRowPosition, + withShiftMask, + withControlMask); + this.selectionLayer.fireCellSelectionEvent( + this.newSelectedColumnPosition, + this.newSelectedRowPosition, + true, + withShiftMask, + withControlMask); + + break; + } + } } else { - // since the calculated target is invalid and - // invalid traversal movement should stop, the new - // selected position is the last valid one - this.newSelectedColumnPosition = this.lastSelectedCellPosition.columnPosition; - this.newSelectedRowPosition = this.lastSelectedCellPosition.rowPosition; + if (!stopTraversalOnInvalid) { + moveLastSelectedUp( + createIncrementalStrategy(traversalStrategy), + withShiftMask, withControlMask); + } else { + // since the calculated target is invalid and + // invalid traversal movement should stop, the + // new selected position is the last valid one + this.newSelectedColumnPosition = this.lastSelectedCellPosition.columnPosition; + this.newSelectedRowPosition = this.lastSelectedCellPosition.rowPosition; + } } } else { + if (stepSize == SelectionLayer.MOVE_ALL && !withShiftMask) { + this.selectionLayer.clear(false); + } + this.selectionLayer.selectCell( this.newSelectedColumnPosition, this.newSelectedRowPosition, @@ -386,7 +479,8 @@ public class MoveCellSelectionCommandHandler extends MoveSelectionCommandHandler this.newSelectedColumnPosition, this.newSelectedRowPosition); if (newSelected != null) { - // if cell has row spanning, ensure that the whole cell is displayed + // if cell has row spanning, ensure that the whole cell is + // displayed this.newSelectedRowPosition = newSelected.getOriginRowPosition() + newSelected.getRowSpan() - 1; } @@ -435,18 +529,51 @@ public class MoveCellSelectionCommandHandler extends MoveSelectionCommandHandler if (!traversalStrategy.isValidTarget(lastSelectedCell, this.selectionLayer.getCellByPosition(this.newSelectedColumnPosition, this.newSelectedRowPosition))) { - if (!stopTraversalOnInvalid) { - moveLastSelectedDown( - createIncrementalStrategy(traversalStrategy), - withShiftMask, withControlMask); + // for MOVE_ALL we need to go backwards to find the last + // valid position + if (stepSize == SelectionLayer.MOVE_ALL) { + for (int i = this.newSelectedRowPosition; i >= 0; i--) { + ILayerCell newPosition = this.selectionLayer.getCellByPosition(this.newSelectedColumnPosition, i); + if (traversalStrategy.isValidTarget(lastSelectedCell, newPosition)) { + this.newSelectedRowPosition = i; + + if (!withShiftMask) { + this.selectionLayer.clear(false); + } + + this.selectionLayer.selectCell( + this.newSelectedColumnPosition, + this.newSelectedRowPosition, + withShiftMask, + withControlMask); + this.selectionLayer.fireCellSelectionEvent( + this.newSelectedColumnPosition, + this.newSelectedRowPosition, + true, + withShiftMask, + withControlMask); + + break; + } + } } else { - // since the calculated target is invalid and - // invalid traversal movement should stop, the new - // selected position is the last valid one - this.newSelectedColumnPosition = this.lastSelectedCellPosition.columnPosition; - this.newSelectedRowPosition = this.lastSelectedCellPosition.rowPosition; + if (!stopTraversalOnInvalid) { + moveLastSelectedDown( + createIncrementalStrategy(traversalStrategy), + withShiftMask, withControlMask); + } else { + // since the calculated target is invalid and + // invalid traversal movement should stop, the + // new selected position is the last valid one + this.newSelectedColumnPosition = this.lastSelectedCellPosition.columnPosition; + this.newSelectedRowPosition = this.lastSelectedCellPosition.rowPosition; + } } } else { + if (stepSize == SelectionLayer.MOVE_ALL && !withShiftMask) { + this.selectionLayer.clear(false); + } + this.selectionLayer.selectCell( this.newSelectedColumnPosition, this.newSelectedRowPosition, diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/action/MoveToEndAction.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/action/MoveToEndAction.java index bc681f88..1a9b0190 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/action/MoveToEndAction.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/selection/action/MoveToEndAction.java @@ -40,7 +40,8 @@ public class MoveToEndAction extends AbstractKeySelectAction { isShiftMask(), isControlMask())); } else { - // if the CTRL key is pressed, we need to move the selection to the first cell + // if the CTRL key is pressed, we need to move the selection to the + // last cell natTable.doCommand( new MoveSelectionCommand( MoveDirectionEnum.RIGHT, |