From 0385c0fdf5b2f7a5ccf5fa75265ce9d90ee63cc2 Mon Sep 17 00:00:00 2001 From: Dirk Fauth Date: Thu, 8 Aug 2024 07:35:54 +0200 Subject: [PATCH] Fixes #109 - ColumnGroup not updated on ResetColumnReorderCommand --- .../ColumnGroupHeaderLayerTest.java | 420 +++++++++++++++++- .../performance/RowGroupHeaderLayerTest.java | 418 ++++++++++++++++- .../group/performance/GroupModel.java | 33 +- 3 files changed, 868 insertions(+), 3 deletions(-) diff --git a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/group/performance/ColumnGroupHeaderLayerTest.java b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/group/performance/ColumnGroupHeaderLayerTest.java index 5b92546a3..93b85f697 100644 --- a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/group/performance/ColumnGroupHeaderLayerTest.java +++ b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/group/performance/ColumnGroupHeaderLayerTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2023 Dirk Fauth. + * Copyright (c) 2019, 2024 Dirk Fauth. * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 @@ -11943,6 +11943,424 @@ public void shouldHandleResetOfColumnReordering() { verifyCleanState(); } + @Test + public void shouldHandleResetOfColumnReorderEndOfGroupRightToLeft() { + // remove all groups + this.columnGroupHeaderLayer.removeGroup(0); + this.columnGroupHeaderLayer.removeGroup(4); + this.columnGroupHeaderLayer.removeGroup(8); + this.columnGroupHeaderLayer.removeGroup(11); + + // reorder column 8 to position 4 + this.gridLayer.doCommand(new ColumnReorderCommand(this.gridLayer, 8, 4)); + + this.columnGroupHeaderLayer.addGroup("Person", 0, 4); + Group group = this.groupModel.getGroupByPosition(0); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(2)); + assertTrue(group.hasMember(7)); + + // reset reordering + this.gridLayer.doCommand(new ResetColumnReorderCommand()); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(3, group.getOriginalSpan()); + assertEquals(3, group.getVisibleSpan()); + + assertEquals(3, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(2)); + } + + @Test + public void shouldHandleResetOfColumnReorderMiddleOfGroupRightToLeft() { + // remove all groups + this.columnGroupHeaderLayer.removeGroup(0); + this.columnGroupHeaderLayer.removeGroup(4); + this.columnGroupHeaderLayer.removeGroup(8); + this.columnGroupHeaderLayer.removeGroup(11); + + // reorder column 8 to position 3 + this.gridLayer.doCommand(new ColumnReorderCommand(this.gridLayer, 8, 3)); + + this.columnGroupHeaderLayer.addGroup("Person", 0, 4); + Group group = this.groupModel.getGroupByPosition(0); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(2)); + assertTrue(group.hasMember(7)); + + // reset reordering + this.gridLayer.doCommand(new ResetColumnReorderCommand()); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(3, group.getOriginalSpan()); + assertEquals(3, group.getVisibleSpan()); + + assertEquals(3, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(2)); + } + + @Test + public void shouldHandleResetOfColumnReorderStartOfGroupRightToLeft() { + // remove all groups + this.columnGroupHeaderLayer.removeGroup(0); + this.columnGroupHeaderLayer.removeGroup(4); + this.columnGroupHeaderLayer.removeGroup(8); + this.columnGroupHeaderLayer.removeGroup(11); + + // reorder column 8 to position 1 + this.gridLayer.doCommand(new ColumnReorderCommand(this.gridLayer, 8, 1)); + + this.columnGroupHeaderLayer.addGroup("Person", 7, 4); + Group group = this.groupModel.getGroupByPosition(0); + + assertEquals(7, group.getStartIndex()); + assertEquals(7, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(2)); + assertTrue(group.hasMember(7)); + + // reset reordering + this.gridLayer.doCommand(new ResetColumnReorderCommand()); + + // as there is only a single column moved out of the group, the group is + // kept and the start index is updated. + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(3, group.getOriginalSpan()); + assertEquals(3, group.getVisibleSpan()); + + assertEquals(3, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(2)); + } + + @Test + public void shouldHandleResetOfColumnReorderEndOfGroupLeftToRight() { + // remove all groups + this.columnGroupHeaderLayer.removeGroup(0); + this.columnGroupHeaderLayer.removeGroup(4); + this.columnGroupHeaderLayer.removeGroup(8); + this.columnGroupHeaderLayer.removeGroup(11); + + // reorder column 1 to position 8 + this.gridLayer.doCommand(new ColumnReorderCommand(this.gridLayer, 2, 8)); + + this.columnGroupHeaderLayer.addGroup("Address", 4, 4); + Group group = this.groupModel.getGroupByPosition(4); + + assertEquals(4, group.getStartIndex()); + assertEquals(4, group.getVisibleStartIndex()); + assertEquals(3, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(6)); + assertTrue(group.hasMember(1)); + + // reset reordering + this.gridLayer.doCommand(new ResetColumnReorderCommand()); + + assertEquals(4, group.getStartIndex()); + assertEquals(4, group.getVisibleStartIndex()); + assertEquals(4, group.getVisibleStartPosition()); + assertEquals(3, group.getOriginalSpan()); + assertEquals(3, group.getVisibleSpan()); + + assertEquals(3, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(6)); + } + + @Test + public void shouldHandleResetOfColumnReorderMiddleOfGroupLeftToRight() { + // remove all groups + this.columnGroupHeaderLayer.removeGroup(0); + this.columnGroupHeaderLayer.removeGroup(4); + this.columnGroupHeaderLayer.removeGroup(8); + this.columnGroupHeaderLayer.removeGroup(11); + + // reorder column 1 to position 5 + this.gridLayer.doCommand(new ColumnReorderCommand(this.gridLayer, 2, 6)); + + this.columnGroupHeaderLayer.addGroup("Address", 4, 4); + Group group = this.groupModel.getGroupByPosition(4); + + assertEquals(4, group.getStartIndex()); + assertEquals(4, group.getVisibleStartIndex()); + assertEquals(3, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(6)); + assertTrue(group.hasMember(1)); + + // reset reordering + this.gridLayer.doCommand(new ResetColumnReorderCommand()); + + assertEquals(4, group.getStartIndex()); + assertEquals(4, group.getVisibleStartIndex()); + assertEquals(4, group.getVisibleStartPosition()); + assertEquals(3, group.getOriginalSpan()); + assertEquals(3, group.getVisibleSpan()); + + assertEquals(3, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(6)); + } + + @Test + public void shouldHandleResetOfColumnReorderStartOfGroupLeftToRight() { + // remove all groups + this.columnGroupHeaderLayer.removeGroup(0); + this.columnGroupHeaderLayer.removeGroup(4); + this.columnGroupHeaderLayer.removeGroup(8); + this.columnGroupHeaderLayer.removeGroup(11); + + // reorder column 1 to position 4 + this.gridLayer.doCommand(new ColumnReorderCommand(this.gridLayer, 2, 5)); + + this.columnGroupHeaderLayer.addGroup("Address", 1, 4); + Group group = this.groupModel.getGroupByPosition(4); + + assertEquals(1, group.getStartIndex()); + assertEquals(1, group.getVisibleStartIndex()); + assertEquals(3, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(6)); + assertTrue(group.hasMember(1)); + + // reset reordering + this.gridLayer.doCommand(new ResetColumnReorderCommand()); + + assertEquals(4, group.getStartIndex()); + assertEquals(4, group.getVisibleStartIndex()); + assertEquals(4, group.getVisibleStartPosition()); + assertEquals(3, group.getOriginalSpan()); + assertEquals(3, group.getVisibleSpan()); + + assertEquals(3, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(6)); + } + + @Test + public void shouldHandleResetOfColumnReorderEndOfGroupRightToLeftSameSize() { + // remove all groups + this.columnGroupHeaderLayer.removeGroup(0); + this.columnGroupHeaderLayer.removeGroup(4); + this.columnGroupHeaderLayer.removeGroup(8); + this.columnGroupHeaderLayer.removeGroup(11); + + // reorder column 8 to position 3 + // reorder column 9 to position 4 + this.gridLayer.doCommand(new ColumnReorderCommand(this.gridLayer, 8, 3)); + this.gridLayer.doCommand(new ColumnReorderCommand(this.gridLayer, 9, 4)); + + this.columnGroupHeaderLayer.addGroup("Person", 0, 4); + Group group = this.groupModel.getGroupByPosition(0); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(7)); + assertTrue(group.hasMember(8)); + + // reset reordering + this.gridLayer.doCommand(new ResetColumnReorderCommand()); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(2, group.getOriginalSpan()); + assertEquals(2, group.getVisibleSpan()); + + assertEquals(2, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + } + + @Test + public void shouldHandleResetOfColumnReorderStartOfGroupRightToLeftSameSize() { + // remove all groups + this.columnGroupHeaderLayer.removeGroup(0); + this.columnGroupHeaderLayer.removeGroup(4); + this.columnGroupHeaderLayer.removeGroup(8); + this.columnGroupHeaderLayer.removeGroup(11); + + // reorder column 8 to position 1 + // reorder column 9 to position 2 + this.gridLayer.doCommand(new ColumnReorderCommand(this.gridLayer, 8, 1)); + this.gridLayer.doCommand(new ColumnReorderCommand(this.gridLayer, 9, 2)); + + this.columnGroupHeaderLayer.addGroup("Person", 7, 4); + Group group = this.groupModel.getGroupByPosition(0); + + assertEquals(7, group.getStartIndex()); + assertEquals(7, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(7)); + assertTrue(group.hasMember(8)); + + // reset reordering + this.gridLayer.doCommand(new ResetColumnReorderCommand()); + + // the reset splits the group into two subgroups with same size, the + // most left is kept in this case + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(2, group.getOriginalSpan()); + assertEquals(2, group.getVisibleSpan()); + + assertEquals(2, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + } + + @Test + public void shouldHandleResetOfColumnReorderEndOfGroupLeftToRightSameSize() { + // remove all groups + this.columnGroupHeaderLayer.removeGroup(0); + this.columnGroupHeaderLayer.removeGroup(4); + this.columnGroupHeaderLayer.removeGroup(8); + this.columnGroupHeaderLayer.removeGroup(11); + + // reorder column 0 to position 8 + // reorder column 1 to position 9 + this.gridLayer.doCommand(new ColumnReorderCommand(this.gridLayer, 2, 7)); + this.gridLayer.doCommand(new ColumnReorderCommand(this.gridLayer, 1, 7)); + + this.columnGroupHeaderLayer.addGroup("Address", 4, 4); + Group group = this.groupModel.getGroupByPosition(4); + + assertEquals(4, group.getStartIndex()); + assertEquals(4, group.getVisibleStartIndex()); + assertEquals(2, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + + // reset reordering + this.gridLayer.doCommand(new ResetColumnReorderCommand()); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(2, group.getOriginalSpan()); + assertEquals(2, group.getVisibleSpan()); + + assertEquals(2, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + } + + @Test + public void shouldHandleResetOfColumnReorderStartOfGroupLeftToRightSameSize() { + // remove all groups + this.columnGroupHeaderLayer.removeGroup(0); + this.columnGroupHeaderLayer.removeGroup(4); + this.columnGroupHeaderLayer.removeGroup(8); + this.columnGroupHeaderLayer.removeGroup(11); + + // reorder column 0 to position 4 + // reorder column 1 to position 5 + this.gridLayer.doCommand(new ColumnReorderCommand(this.gridLayer, 1, 5)); + this.gridLayer.doCommand(new ColumnReorderCommand(this.gridLayer, 1, 5)); + + this.columnGroupHeaderLayer.addGroup("Address", 0, 4); + Group group = this.groupModel.getGroupByPosition(4); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(2, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + + // reset reordering + this.gridLayer.doCommand(new ResetColumnReorderCommand()); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(2, group.getOriginalSpan()); + assertEquals(2, group.getVisibleSpan()); + + assertEquals(2, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + } + @Test public void shouldReorderGroupWithHiddenColumns() { // remove the first column group diff --git a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/group/performance/RowGroupHeaderLayerTest.java b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/group/performance/RowGroupHeaderLayerTest.java index 7b92d7d77..66aa545f7 100644 --- a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/group/performance/RowGroupHeaderLayerTest.java +++ b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/group/performance/RowGroupHeaderLayerTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2023 Dirk Fauth. + * Copyright (c) 2019, 2024 Dirk Fauth. * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 @@ -11921,6 +11921,422 @@ public void shouldHandleResetOfRowReordering() { verifyCleanState(); } + @Test + public void shouldHandleResetOfRowReorderEndOfGroupRightToLeft() { + // remove all groups + this.rowGroupHeaderLayer.removeGroup(0); + this.rowGroupHeaderLayer.removeGroup(4); + this.rowGroupHeaderLayer.removeGroup(8); + this.rowGroupHeaderLayer.removeGroup(11); + + // reorder row 8 to position 4 + this.gridLayer.doCommand(new RowReorderCommand(this.gridLayer, 8, 4)); + + this.rowGroupHeaderLayer.addGroup("Person", 0, 4); + Group group = this.groupModel.getGroupByPosition(0); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(2)); + assertTrue(group.hasMember(7)); + + // reset reordering + this.gridLayer.doCommand(new ResetRowReorderCommand()); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(3, group.getOriginalSpan()); + assertEquals(3, group.getVisibleSpan()); + + assertEquals(3, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(2)); + } + + @Test + public void shouldHandleResetOfRowReorderMiddleOfGroupRightToLeft() { + // remove all groups + this.rowGroupHeaderLayer.removeGroup(0); + this.rowGroupHeaderLayer.removeGroup(4); + this.rowGroupHeaderLayer.removeGroup(8); + this.rowGroupHeaderLayer.removeGroup(11); + + // reorder row 8 to position 3 + this.gridLayer.doCommand(new RowReorderCommand(this.gridLayer, 8, 3)); + + this.rowGroupHeaderLayer.addGroup("Person", 0, 4); + Group group = this.groupModel.getGroupByPosition(0); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(2)); + assertTrue(group.hasMember(7)); + + // reset reordering + this.gridLayer.doCommand(new ResetRowReorderCommand()); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(3, group.getOriginalSpan()); + assertEquals(3, group.getVisibleSpan()); + + assertEquals(3, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(2)); + } + + @Test + public void shouldHandleResetOfRowReorderStartOfGroupRightToLeft() { + // remove all groups + this.rowGroupHeaderLayer.removeGroup(0); + this.rowGroupHeaderLayer.removeGroup(4); + this.rowGroupHeaderLayer.removeGroup(8); + this.rowGroupHeaderLayer.removeGroup(11); + + // reorder row 8 to position 1 + this.gridLayer.doCommand(new RowReorderCommand(this.gridLayer, 8, 1)); + + this.rowGroupHeaderLayer.addGroup("Person", 7, 4); + Group group = this.groupModel.getGroupByPosition(0); + + assertEquals(7, group.getStartIndex()); + assertEquals(7, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(2)); + assertTrue(group.hasMember(7)); + + // reset reordering + this.gridLayer.doCommand(new ResetRowReorderCommand()); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(3, group.getOriginalSpan()); + assertEquals(3, group.getVisibleSpan()); + + assertEquals(3, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(2)); + } + + @Test + public void shouldHandleResetOfRowReorderEndOfGroupLeftToRight() { + // remove all groups + this.rowGroupHeaderLayer.removeGroup(0); + this.rowGroupHeaderLayer.removeGroup(4); + this.rowGroupHeaderLayer.removeGroup(8); + this.rowGroupHeaderLayer.removeGroup(11); + + // reorder row 1 to position 8 + this.gridLayer.doCommand(new RowReorderCommand(this.gridLayer, 2, 8)); + + this.rowGroupHeaderLayer.addGroup("Address", 4, 4); + Group group = this.groupModel.getGroupByPosition(4); + + assertEquals(4, group.getStartIndex()); + assertEquals(4, group.getVisibleStartIndex()); + assertEquals(3, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(6)); + assertTrue(group.hasMember(1)); + + // reset reordering + this.gridLayer.doCommand(new ResetRowReorderCommand()); + + assertEquals(4, group.getStartIndex()); + assertEquals(4, group.getVisibleStartIndex()); + assertEquals(4, group.getVisibleStartPosition()); + assertEquals(3, group.getOriginalSpan()); + assertEquals(3, group.getVisibleSpan()); + + assertEquals(3, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(6)); + } + + @Test + public void shouldHandleResetOfRowReorderMiddleOfGroupLeftToRight() { + // remove all groups + this.rowGroupHeaderLayer.removeGroup(0); + this.rowGroupHeaderLayer.removeGroup(4); + this.rowGroupHeaderLayer.removeGroup(8); + this.rowGroupHeaderLayer.removeGroup(11); + + // reorder row 1 to position 5 + this.gridLayer.doCommand(new RowReorderCommand(this.gridLayer, 2, 6)); + + this.rowGroupHeaderLayer.addGroup("Address", 4, 4); + Group group = this.groupModel.getGroupByPosition(4); + + assertEquals(4, group.getStartIndex()); + assertEquals(4, group.getVisibleStartIndex()); + assertEquals(3, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(6)); + assertTrue(group.hasMember(1)); + + // reset reordering + this.gridLayer.doCommand(new ResetRowReorderCommand()); + + assertEquals(4, group.getStartIndex()); + assertEquals(4, group.getVisibleStartIndex()); + assertEquals(4, group.getVisibleStartPosition()); + assertEquals(3, group.getOriginalSpan()); + assertEquals(3, group.getVisibleSpan()); + + assertEquals(3, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(6)); + } + + @Test + public void shouldHandleResetOfRowReorderStartOfGroupLeftToRight() { + // remove all groups + this.rowGroupHeaderLayer.removeGroup(0); + this.rowGroupHeaderLayer.removeGroup(4); + this.rowGroupHeaderLayer.removeGroup(8); + this.rowGroupHeaderLayer.removeGroup(11); + + // reorder row 1 to position 4 + this.gridLayer.doCommand(new RowReorderCommand(this.gridLayer, 2, 5)); + + this.rowGroupHeaderLayer.addGroup("Address", 1, 4); + Group group = this.groupModel.getGroupByPosition(4); + + assertEquals(1, group.getStartIndex()); + assertEquals(1, group.getVisibleStartIndex()); + assertEquals(3, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(6)); + assertTrue(group.hasMember(1)); + + // reset reordering + this.gridLayer.doCommand(new ResetRowReorderCommand()); + + assertEquals(4, group.getStartIndex()); + assertEquals(4, group.getVisibleStartIndex()); + assertEquals(4, group.getVisibleStartPosition()); + assertEquals(3, group.getOriginalSpan()); + assertEquals(3, group.getVisibleSpan()); + + assertEquals(3, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(6)); + } + + @Test + public void shouldHandleResetOfRowReorderEndOfGroupRightToLeftSameSize() { + // remove all groups + this.rowGroupHeaderLayer.removeGroup(0); + this.rowGroupHeaderLayer.removeGroup(4); + this.rowGroupHeaderLayer.removeGroup(8); + this.rowGroupHeaderLayer.removeGroup(11); + + // reorder row 8 to position 3 + // reorder row 9 to position 4 + this.gridLayer.doCommand(new RowReorderCommand(this.gridLayer, 8, 3)); + this.gridLayer.doCommand(new RowReorderCommand(this.gridLayer, 9, 4)); + + this.rowGroupHeaderLayer.addGroup("Person", 0, 4); + Group group = this.groupModel.getGroupByPosition(0); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(7)); + assertTrue(group.hasMember(8)); + + // reset reordering + this.gridLayer.doCommand(new ResetRowReorderCommand()); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(2, group.getOriginalSpan()); + assertEquals(2, group.getVisibleSpan()); + + assertEquals(2, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + } + + @Test + public void shouldHandleResetOfRowReorderStartOfGroupRightToLeftSameSize() { + // remove all groups + this.rowGroupHeaderLayer.removeGroup(0); + this.rowGroupHeaderLayer.removeGroup(4); + this.rowGroupHeaderLayer.removeGroup(8); + this.rowGroupHeaderLayer.removeGroup(11); + + // reorder row 8 to position 1 + // reorder row 9 to position 2 + this.gridLayer.doCommand(new RowReorderCommand(this.gridLayer, 8, 1)); + this.gridLayer.doCommand(new RowReorderCommand(this.gridLayer, 9, 2)); + + this.rowGroupHeaderLayer.addGroup("Person", 7, 4); + Group group = this.groupModel.getGroupByPosition(0); + + assertEquals(7, group.getStartIndex()); + assertEquals(7, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + assertTrue(group.hasMember(7)); + assertTrue(group.hasMember(8)); + + // reset reordering + this.gridLayer.doCommand(new ResetRowReorderCommand()); + + // the reset splits the group into two subgroups with same size, the + // most left is kept in this case + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(2, group.getOriginalSpan()); + assertEquals(2, group.getVisibleSpan()); + + assertEquals(2, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + } + + @Test + public void shouldHandleResetOfRowReorderEndOfGroupLeftToRightSameSize() { + // remove all groups + this.rowGroupHeaderLayer.removeGroup(0); + this.rowGroupHeaderLayer.removeGroup(4); + this.rowGroupHeaderLayer.removeGroup(8); + this.rowGroupHeaderLayer.removeGroup(11); + + // reorder row 0 to position 8 + // reorder row 1 to position 9 + this.gridLayer.doCommand(new RowReorderCommand(this.gridLayer, 2, 7)); + this.gridLayer.doCommand(new RowReorderCommand(this.gridLayer, 1, 7)); + + this.rowGroupHeaderLayer.addGroup("Address", 4, 4); + Group group = this.groupModel.getGroupByPosition(4); + + assertEquals(4, group.getStartIndex()); + assertEquals(4, group.getVisibleStartIndex()); + assertEquals(2, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + + // reset reordering + this.gridLayer.doCommand(new ResetRowReorderCommand()); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(2, group.getOriginalSpan()); + assertEquals(2, group.getVisibleSpan()); + + assertEquals(2, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + } + + @Test + public void shouldHandleResetOfRowReorderStartOfGroupLeftToRightSameSize() { + // remove all groups + this.rowGroupHeaderLayer.removeGroup(0); + this.rowGroupHeaderLayer.removeGroup(4); + this.rowGroupHeaderLayer.removeGroup(8); + this.rowGroupHeaderLayer.removeGroup(11); + + // reorder row 0 to position 4 + // reorder row 1 to position 5 + this.gridLayer.doCommand(new RowReorderCommand(this.gridLayer, 1, 5)); + this.gridLayer.doCommand(new RowReorderCommand(this.gridLayer, 1, 5)); + + this.rowGroupHeaderLayer.addGroup("Address", 0, 4); + Group group = this.groupModel.getGroupByPosition(4); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(2, group.getVisibleStartPosition()); + assertEquals(4, group.getOriginalSpan()); + assertEquals(4, group.getVisibleSpan()); + + assertEquals(4, group.getMembers().length); + assertTrue(group.hasMember(4)); + assertTrue(group.hasMember(5)); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + + // reset reordering + this.gridLayer.doCommand(new ResetRowReorderCommand()); + + assertEquals(0, group.getStartIndex()); + assertEquals(0, group.getVisibleStartIndex()); + assertEquals(0, group.getVisibleStartPosition()); + assertEquals(2, group.getOriginalSpan()); + assertEquals(2, group.getVisibleSpan()); + + assertEquals(2, group.getMembers().length); + assertTrue(group.hasMember(0)); + assertTrue(group.hasMember(1)); + } + @Test public void shouldReorderGroupWithHiddenRows() { // remove the first row group diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/group/performance/GroupModel.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/group/performance/GroupModel.java index c6e814e79..5b1f3e5d8 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/group/performance/GroupModel.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/group/performance/GroupModel.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2023 Dirk Fauth. + * Copyright (c) 2019, 2024 Dirk Fauth. * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 @@ -27,6 +27,7 @@ import org.eclipse.collections.api.set.primitive.MutableIntSet; import org.eclipse.collections.impl.factory.primitive.IntLists; import org.eclipse.collections.impl.factory.primitive.IntSets; +import org.eclipse.nebula.widgets.nattable.coordinate.PositionUtil; import org.eclipse.nebula.widgets.nattable.layer.IUniqueIndexLayer; import org.eclipse.nebula.widgets.nattable.persistence.IPersistable; @@ -1202,6 +1203,36 @@ void consistencyCheck(boolean updateStartIndex) { MutableIntList memberPositions = this.members .collectInt(member -> getPositionByIndex(member), IntLists.mutable.empty()); + // check if members are still consecutive + // ignore hidden columns here, as they are handled afterwards + int[][] groupedByContiguous = PositionUtil.getGroupedByContiguous( + memberPositions.primitiveStream().filter(v -> v >= 0).toArray()); + if (groupedByContiguous.length > 1) { + // members are not consecutive anymore + // determine the biggest consecutive group that will remain as + // the group, in case of multiple same size sub-groups, use the + // most left as the remaining group + int[] groupedToKeep = null; + for (int i = 0; i < groupedByContiguous.length; i++) { + int[] notConsecutive = groupedByContiguous[i]; + if (groupedToKeep == null || notConsecutive.length > groupedToKeep.length) { + groupedToKeep = notConsecutive; + } + } + + for (int i = 0; i < groupedByContiguous.length; i++) { + int[] notConsecutive = groupedByContiguous[i]; + if (notConsecutive != groupedToKeep) { + memberPositions.removeAll(notConsecutive); + + MutableIntList notConsecutiveIndexes = IntLists.mutable.of(notConsecutive) + .collectInt(memberPos -> getIndexByPosition(memberPos), IntLists.mutable.empty()); + removeMembers(notConsecutiveIndexes.toArray()); + setOriginalSpan(this.originalSpan - notConsecutive.length); + } + } + } + int hidden = memberPositions.count(pos -> pos == -1); int smallestPosition = memberPositions.select(pos -> pos >= 0).minIfEmpty(-1);