diff options
| author | Dirk Fauth | 2022-11-02 06:27:30 +0000 |
|---|---|---|
| committer | Dirk Fauth | 2022-11-02 06:27:30 +0000 |
| commit | 9455fb8fea92055d2deadb29aa974d38a9756422 (patch) | |
| tree | b30576c2afd41196cbba55113aed13f90c9e21fe | |
| parent | 1aa3202e7759dd103eebce3188ebfc9a96ced6a1 (diff) | |
| download | org.eclipse.nebula.widgets.nattable-9455fb8fea92055d2deadb29aa974d38a9756422.tar.gz org.eclipse.nebula.widgets.nattable-9455fb8fea92055d2deadb29aa974d38a9756422.tar.xz org.eclipse.nebula.widgets.nattable-9455fb8fea92055d2deadb29aa974d38a9756422.zip | |
Bug 580971 - Accumulate sorting columns changes sort sequence
Signed-off-by: Dirk Fauth <dirk.fauth@googlemail.com>
Change-Id: I2e31c4e984614c113f1de0d7a9f16aa5e469f8dd
4 files changed, 425 insertions, 56 deletions
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/sort/command/SortCommandHandler.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/sort/command/SortCommandHandler.java index f82dcbc0..b5644bb0 100644 --- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/sort/command/SortCommandHandler.java +++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/sort/command/SortCommandHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2020 Original authors and others. + * Copyright (c) 2012, 2022 Original authors and others. * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 @@ -44,7 +44,7 @@ public class SortCommandHandler<T> extends AbstractLayerCommandHandler<SortColum if (columnIndex >= 0) { final SortDirectionEnum newSortDirection = (command.getSortDirection() != null) ? command.getSortDirection() - : this.sortModel.getSortDirection(columnIndex).getNextSortDirection(); + : getSortDirectionFromSortModel(columnIndex, command.isAccumulate()); // Fire command - with busy indicator Runnable sortRunner = () -> SortCommandHandler.this.sortModel.sort(columnIndex, newSortDirection, command.isAccumulate()); @@ -58,6 +58,21 @@ public class SortCommandHandler<T> extends AbstractLayerCommandHandler<SortColum return true; } + private SortDirectionEnum getSortDirectionFromSortModel(int columnIndex, boolean accumulate) { + SortDirectionEnum sortDirection = this.sortModel.getSortDirection(columnIndex); + // if there is a sorting applied for multiple columns and the sorting + // should be accumulated and not the last column should be sorted, + // only update the sort direction ASC vs. DESC and avoid to remove + // the sorting + if (accumulate + && sortDirection != SortDirectionEnum.NONE + && this.sortModel.getSortedColumnIndexes().size() > 1 + && this.sortModel.getSortOrder(columnIndex) < this.sortModel.getSortedColumnIndexes().size() - 1) { + return (sortDirection == SortDirectionEnum.ASC) ? SortDirectionEnum.DESC : SortDirectionEnum.ASC; + } + return sortDirection.getNextSortDirection(); + } + @Override public Class<SortColumnCommand> getCommandClass() { return SortColumnCommand.class; diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists.test/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/test/integration/GlazedListsGridLayer.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists.test/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/test/integration/GlazedListsGridLayer.java index 223033c5..a4af1561 100644 --- a/org.eclipse.nebula.widgets.nattable.extension.glazedlists.test/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/test/integration/GlazedListsGridLayer.java +++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists.test/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/test/integration/GlazedListsGridLayer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2020 Original authors and others. + * Copyright (c) 2012, 2022 Original authors and others. * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 @@ -52,24 +52,30 @@ public class GlazedListsGridLayer<T> extends GridLayer { private DefaultBodyLayerStack bodyLayerStack; private ListDataProvider<T> bodyDataProvider; private GlazedListsEventLayer<T> glazedListsEventLayer; + private SortHeaderLayer<T> columnHeaderSortableLayer; - public GlazedListsGridLayer(EventList<T> eventList, String[] propertyNames, + public GlazedListsGridLayer(EventList<T> eventList, + String[] propertyNames, Map<String, String> propertyToLabelMap, IConfigRegistry configRegistry) { this(eventList, propertyNames, propertyToLabelMap, configRegistry, true); } - public GlazedListsGridLayer(EventList<T> eventList, String[] propertyNames, + public GlazedListsGridLayer(EventList<T> eventList, + String[] propertyNames, Map<String, String> propertyToLabelMap, - IConfigRegistry configRegistry, boolean useDefaultConfiguration) { + IConfigRegistry configRegistry, + boolean useDefaultConfiguration) { super(useDefaultConfiguration); // Body - with list event listener // NOTE: Remember to use the SortedList constructor with 'null' for the // Comparator SortedList<T> sortedList = new SortedList<>(eventList, null); - IColumnPropertyAccessor<T> columnPropertyAccessor = new ReflectiveColumnPropertyAccessor<>(propertyNames); - this.bodyDataProvider = new ListDataProvider<>(sortedList, columnPropertyAccessor); + IColumnPropertyAccessor<T> columnPropertyAccessor = + new ReflectiveColumnPropertyAccessor<>(propertyNames); + this.bodyDataProvider = + new ListDataProvider<>(sortedList, columnPropertyAccessor); this.bodyDataLayer = new DataLayer(this.bodyDataProvider); this.glazedListsEventLayer = new GlazedListsEventLayer<>(this.bodyDataLayer, eventList); @@ -77,35 +83,47 @@ public class GlazedListsGridLayer<T> extends GridLayer { this.bodyLayerStack = new DefaultBodyLayerStack(this.glazedListsEventLayer); // Sort Column header - IDataProvider columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap); - this.columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider); - ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer( - this.columnHeaderDataLayer, this.bodyLayerStack, - this.bodyLayerStack.getSelectionLayer()); + IDataProvider columnHeaderDataProvider = + new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap); + this.columnHeaderDataLayer = + new DefaultColumnHeaderDataLayer(columnHeaderDataProvider); + ColumnHeaderLayer columnHeaderLayer = + new ColumnHeaderLayer( + this.columnHeaderDataLayer, + this.bodyLayerStack, + this.bodyLayerStack.getSelectionLayer()); // Auto configure off. Configurations have to applied manually. - SortHeaderLayer<T> columnHeaderSortableLayer = new SortHeaderLayer<>( - columnHeaderLayer, new GlazedListsSortModel<>(sortedList, - columnPropertyAccessor, configRegistry, - this.columnHeaderDataLayer), - false); + this.columnHeaderSortableLayer = + new SortHeaderLayer<>( + columnHeaderLayer, + new GlazedListsSortModel<>( + sortedList, + columnPropertyAccessor, + configRegistry, + this.columnHeaderDataLayer), + false); // Row header - DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(this.bodyDataProvider); - DefaultRowHeaderDataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider); - RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, - this.bodyLayerStack, this.bodyLayerStack.getSelectionLayer()); + DefaultRowHeaderDataProvider rowHeaderDataProvider = + new DefaultRowHeaderDataProvider(this.bodyDataProvider); + DefaultRowHeaderDataLayer rowHeaderDataLayer = + new DefaultRowHeaderDataLayer(rowHeaderDataProvider); + RowHeaderLayer rowHeaderLayer = + new RowHeaderLayer( + rowHeaderDataLayer, + this.bodyLayerStack, + this.bodyLayerStack.getSelectionLayer()); // Corner - DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider( - columnHeaderDataProvider, rowHeaderDataProvider); + DefaultCornerDataProvider cornerDataProvider = + new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider); DataLayer cornerDataLayer = new DataLayer(cornerDataProvider); - CornerLayer cornerLayer = new CornerLayer(cornerDataLayer, - rowHeaderLayer, columnHeaderLayer); + CornerLayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, columnHeaderLayer); // Grid setBodyLayer(this.bodyLayerStack); - setColumnHeaderLayer(columnHeaderSortableLayer); + setColumnHeaderLayer(this.columnHeaderSortableLayer); setRowHeaderLayer(rowHeaderLayer); setCornerLayer(cornerLayer); } @@ -133,4 +151,8 @@ public class GlazedListsGridLayer<T> extends GridLayer { public GlazedListsEventLayer<T> getGlazedListsEventLayer() { return this.glazedListsEventLayer; } + + public SortHeaderLayer<T> getSortHeaderLayer() { + return this.columnHeaderSortableLayer; + } } diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists.test/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/test/integration/SortIntegrationTest.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists.test/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/test/integration/SortIntegrationTest.java index 93f12d24..1daef870 100644 --- a/org.eclipse.nebula.widgets.nattable.extension.glazedlists.test/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/test/integration/SortIntegrationTest.java +++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists.test/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/test/integration/SortIntegrationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2020 Original authors and others. + * Copyright (c) 2012, 2022 Original authors and others. * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 @@ -13,6 +13,7 @@ package org.eclipse.nebula.widgets.nattable.extension.glazedlists.test.integration; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -30,7 +31,10 @@ import org.eclipse.nebula.widgets.nattable.extension.glazedlists.fixture.NatTabl import org.eclipse.nebula.widgets.nattable.layer.DataLayer; import org.eclipse.nebula.widgets.nattable.layer.NoScalingDpiConverter; import org.eclipse.nebula.widgets.nattable.layer.command.ConfigureScalingCommand; +import org.eclipse.nebula.widgets.nattable.sort.ISortModel; import org.eclipse.nebula.widgets.nattable.sort.SortConfigAttributes; +import org.eclipse.nebula.widgets.nattable.sort.SortDirectionEnum; +import org.eclipse.nebula.widgets.nattable.sort.command.SortColumnCommand; import org.eclipse.nebula.widgets.nattable.sort.config.DefaultSortConfiguration; import org.eclipse.nebula.widgets.nattable.style.DisplayMode; import org.eclipse.swt.SWT; @@ -49,14 +53,15 @@ public class SortIntegrationTest { @Before public void setup() { - EventList<RowDataFixture> eventList = GlazedLists - .eventList(RowDataListFixture.getList().subList(0, 4)); + EventList<RowDataFixture> eventList = + GlazedLists.eventList(RowDataListFixture.getList().subList(0, 4)); ConfigRegistry configRegistry = new ConfigRegistry(); this.gridLayerStack = new GlazedListsGridLayer<>( GlazedLists.threadSafeList(eventList), RowDataListFixture.getPropertyNames(), - RowDataListFixture.getPropertyToLabelMap(), configRegistry); + RowDataListFixture.getPropertyToLabelMap(), + configRegistry); this.nattable = new NatTableFixture(this.gridLayerStack, false); this.nattable.setConfigRegistry(configRegistry); @@ -109,7 +114,8 @@ public class SortIntegrationTest { // Disable sorting on column 2 - null comparator this.nattable.getConfigRegistry().registerConfigAttribute( - SortConfigAttributes.SORT_COMPARATOR, new NullComparator(), + SortConfigAttributes.SORT_COMPARATOR, + new NullComparator(), DisplayMode.NORMAL, TEST_LABEL); altClickColumn2Header(); @@ -133,7 +139,8 @@ public class SortIntegrationTest { // Custom comparator on column 2 this.nattable.getConfigRegistry().registerConfigAttribute( - SortConfigAttributes.SORT_COMPARATOR, getGEAtTopComparator(), + SortConfigAttributes.SORT_COMPARATOR, + getGEAtTopComparator(), DisplayMode.NORMAL, TEST_LABEL); altClickColumn2Header(); @@ -196,18 +203,326 @@ public class SortIntegrationTest { assertColumn2AscendingSort(); } + @Test + public void shouldSortColumnByCommand() { + ISortModel sortModel = this.gridLayerStack.getSortHeaderLayer().getSortModel(); + assertTrue("Sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(1, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + } + + @Test + public void shouldChangeSortColumnByCommand() { + ISortModel sortModel = this.gridLayerStack.getSortHeaderLayer().getSortModel(); + assertTrue("Sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(1, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + + // sort another column + this.nattable.doCommand(new SortColumnCommand(this.nattable, 4)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(1, sortModel.getSortedColumnIndexes().size()); + assertEquals(3, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(3)); + } + + @Test + public void shouldChangeSortDirectionByCommand() { + ISortModel sortModel = this.gridLayerStack.getSortHeaderLayer().getSortModel(); + assertTrue("Sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(1, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + + // sort column again to change sort direction + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(1, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(SortDirectionEnum.DESC, sortModel.getSortDirection(2)); + } + + @Test + public void shouldRemoveSortByCommand() { + ISortModel sortModel = this.gridLayerStack.getSortHeaderLayer().getSortModel(); + assertTrue("Sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(1, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + + // sort column again to change sort direction + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3)); + // sort column again to remove sorting + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3)); + + assertTrue("Sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(0, sortModel.getSortedColumnIndexes().size()); + } + + @Test + public void shouldAppendSortColumnsByCommand() { + ISortModel sortModel = this.gridLayerStack.getSortHeaderLayer().getSortModel(); + assertTrue("Sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(1, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + + // sort additional column + this.nattable.doCommand(new SortColumnCommand(this.nattable, 4, true)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(2, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(3, sortModel.getSortedColumnIndexes().get(1).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(3)); + + // sort additional column + this.nattable.doCommand(new SortColumnCommand(this.nattable, 5, true)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(3, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(3, sortModel.getSortedColumnIndexes().get(1).intValue()); + assertEquals(4, sortModel.getSortedColumnIndexes().get(2).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(3)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(4)); + } + + @Test + public void shouldChangeLastAppendedSortColumnByCommand() { + ISortModel sortModel = this.gridLayerStack.getSortHeaderLayer().getSortModel(); + assertTrue("Sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(1, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + + // sort additional columns + this.nattable.doCommand(new SortColumnCommand(this.nattable, 4, true)); + this.nattable.doCommand(new SortColumnCommand(this.nattable, 5, true)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(3, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(3, sortModel.getSortedColumnIndexes().get(1).intValue()); + assertEquals(4, sortModel.getSortedColumnIndexes().get(2).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(3)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(4)); + + // sort last sorted column again to change sort direction + this.nattable.doCommand(new SortColumnCommand(this.nattable, 5, true)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(3, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(3, sortModel.getSortedColumnIndexes().get(1).intValue()); + assertEquals(4, sortModel.getSortedColumnIndexes().get(2).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(3)); + assertEquals(SortDirectionEnum.DESC, sortModel.getSortDirection(4)); + } + + @Test + public void shouldRemoveLastAppendedSortColumnByCommand() { + ISortModel sortModel = this.gridLayerStack.getSortHeaderLayer().getSortModel(); + assertTrue("Sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(1, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + + // sort additional columns + this.nattable.doCommand(new SortColumnCommand(this.nattable, 4, true)); + this.nattable.doCommand(new SortColumnCommand(this.nattable, 5, true)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(3, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(3, sortModel.getSortedColumnIndexes().get(1).intValue()); + assertEquals(4, sortModel.getSortedColumnIndexes().get(2).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(3)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(4)); + + // sort last sorted column again twice to remove sorting + this.nattable.doCommand(new SortColumnCommand(this.nattable, 5, true)); + this.nattable.doCommand(new SortColumnCommand(this.nattable, 5, true)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(2, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(3, sortModel.getSortedColumnIndexes().get(1).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(3)); + } + + @Test + public void shouldChangeFirstAppendedSortColumnByCommand() { + ISortModel sortModel = this.gridLayerStack.getSortHeaderLayer().getSortModel(); + assertTrue("Sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(1, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + + // sort additional columns + this.nattable.doCommand(new SortColumnCommand(this.nattable, 4, true)); + this.nattable.doCommand(new SortColumnCommand(this.nattable, 5, true)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(3, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(3, sortModel.getSortedColumnIndexes().get(1).intValue()); + assertEquals(4, sortModel.getSortedColumnIndexes().get(2).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(3)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(4)); + + // sort first sorted column again to change sort direction + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3, true)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(3, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(3, sortModel.getSortedColumnIndexes().get(1).intValue()); + assertEquals(4, sortModel.getSortedColumnIndexes().get(2).intValue()); + assertEquals(SortDirectionEnum.DESC, sortModel.getSortDirection(2)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(3)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(4)); + } + + @Test + public void shouldNotRemoveFirstAppendedSortColumnByCommand() { + ISortModel sortModel = this.gridLayerStack.getSortHeaderLayer().getSortModel(); + assertTrue("Sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(1, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + + // sort additional columns + this.nattable.doCommand(new SortColumnCommand(this.nattable, 4, true)); + this.nattable.doCommand(new SortColumnCommand(this.nattable, 5, true)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(3, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(3, sortModel.getSortedColumnIndexes().get(1).intValue()); + assertEquals(4, sortModel.getSortedColumnIndexes().get(2).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(3)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(4)); + + // sort first sorted column again to change sort direction + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3, true)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(3, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(3, sortModel.getSortedColumnIndexes().get(1).intValue()); + assertEquals(4, sortModel.getSortedColumnIndexes().get(2).intValue()); + assertEquals(SortDirectionEnum.DESC, sortModel.getSortDirection(2)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(3)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(4)); + + // sort first sorted column again to change sort direction, it should + // not be removed + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3, true)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(3, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(3, sortModel.getSortedColumnIndexes().get(1).intValue()); + assertEquals(4, sortModel.getSortedColumnIndexes().get(2).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(3)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(4)); + } + + @Test + public void shouldUpdateFirstAppendedSortColumnOnlyIfNotAccumulateByCommand() { + ISortModel sortModel = this.gridLayerStack.getSortHeaderLayer().getSortModel(); + assertTrue("Sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(1, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + + // sort additional columns + this.nattable.doCommand(new SortColumnCommand(this.nattable, 4, true)); + this.nattable.doCommand(new SortColumnCommand(this.nattable, 5, true)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(3, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(3, sortModel.getSortedColumnIndexes().get(1).intValue()); + assertEquals(4, sortModel.getSortedColumnIndexes().get(2).intValue()); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(2)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(3)); + assertEquals(SortDirectionEnum.ASC, sortModel.getSortDirection(4)); + + // sort first sorted column again without accumulate to change sort + // direction and remove other column sortings + this.nattable.doCommand(new SortColumnCommand(this.nattable, 3)); + + assertFalse("No sorting applied", sortModel.getSortedColumnIndexes().isEmpty()); + assertEquals(1, sortModel.getSortedColumnIndexes().size()); + assertEquals(2, sortModel.getSortedColumnIndexes().get(0).intValue()); + assertEquals(SortDirectionEnum.DESC, sortModel.getSortDirection(2)); + } + // Convenience methods private void altShiftClickColumn3Header() { this.nattable.forceFocus(); - SWTUtils.leftClick(DataLayer.DEFAULT_COLUMN_WIDTH * 3, 15, SWT.ALT - | SWT.SHIFT, this.nattable); + SWTUtils.leftClick(DataLayer.DEFAULT_COLUMN_WIDTH * 3, 15, SWT.ALT | SWT.SHIFT, this.nattable); } private void altClickColumn2Header() { this.nattable.forceFocus(); - SWTUtils.leftClick(DataLayer.DEFAULT_COLUMN_WIDTH * 2, 15, SWT.ALT, - this.nattable); + SWTUtils.leftClick(DataLayer.DEFAULT_COLUMN_WIDTH * 2, 15, SWT.ALT, this.nattable); } private Comparator<?> getGEAtTopComparator() { diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/NatTableComparatorChooser.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/NatTableComparatorChooser.java index a21c0c5d..54c53e85 100644 --- a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/NatTableComparatorChooser.java +++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/NatTableComparatorChooser.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2020 Original authors and others. + * Copyright (c) 2012, 2022 Original authors and others. * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 @@ -25,19 +25,18 @@ import ca.odell.glazedlists.SortedList; import ca.odell.glazedlists.gui.AbstractTableComparatorChooser; import ca.odell.glazedlists.gui.TableFormat; -public class NatTableComparatorChooser<T> extends - AbstractTableComparatorChooser<T> { +public class NatTableComparatorChooser<T> extends AbstractTableComparatorChooser<T> { - public NatTableComparatorChooser(SortedList<T> sortedList, - TableFormat<T> tableFormat) { + public NatTableComparatorChooser(SortedList<T> sortedList, TableFormat<T> tableFormat) { super(sortedList, tableFormat); } - void sort(int columnIndex, SortDirectionEnum sortDirection, - boolean accumulate) { + void sort(int columnIndex, SortDirectionEnum sortDirection, boolean accumulate) { + if (getComparatorsForColumn(columnIndex).isEmpty()) { return; } + if (!accumulate) { clearComparator(); } @@ -47,12 +46,18 @@ public class NatTableComparatorChooser<T> extends removeSortingColumnIndex(columnIndex); break; case ASC: - removeSortingColumnIndex(columnIndex); - appendComparator(columnIndex, 0, false); + if (isColumnIndexSorted(columnIndex)) { + updateSortingColumnIndex(columnIndex, false); + } else { + appendComparator(columnIndex, 0, false); + } break; case DESC: - removeSortingColumnIndex(columnIndex); - appendComparator(columnIndex, 0, true); + if (isColumnIndexSorted(columnIndex)) { + updateSortingColumnIndex(columnIndex, true); + } else { + appendComparator(columnIndex, 0, true); + } break; default: break; @@ -65,8 +70,7 @@ public class NatTableComparatorChooser<T> extends for (int sortingColumnIndex : getSortingColumns()) { if (sortingColumnIndex != columnIndex) { boolean reverse = isColumnReverse(sortingColumnIndex); - comparatorInfos.add(new ComparatorInfo(sortingColumnIndex, - reverse)); + comparatorInfos.add(new ComparatorInfo(sortingColumnIndex, reverse)); } } @@ -74,8 +78,23 @@ public class NatTableComparatorChooser<T> extends // Rebuild comparators for (ComparatorInfo comparatorInfo : comparatorInfos) { - appendComparator(comparatorInfo.columnIndex, 0, - comparatorInfo.isReverse); + appendComparator(comparatorInfo.columnIndex, 0, comparatorInfo.isReverse); + } + } + + private void updateSortingColumnIndex(int columnIndex, boolean newReverse) { + // Save comparators + List<ComparatorInfo> comparatorInfos = new ArrayList<>(); + for (int sortingColumnIndex : getSortingColumns()) { + boolean reverse = (sortingColumnIndex != columnIndex) ? isColumnReverse(sortingColumnIndex) : newReverse; + comparatorInfos.add(new ComparatorInfo(sortingColumnIndex, reverse)); + } + + clearComparator(); + + // Rebuild comparators + for (ComparatorInfo comparatorInfo : comparatorInfos) { + appendComparator(comparatorInfo.columnIndex, 0, comparatorInfo.isReverse); } } @@ -84,8 +103,7 @@ public class NatTableComparatorChooser<T> extends } public SortDirectionEnum getSortDirectionForColumnIndex(int columnIndex) { - boolean sorted = getSortingColumns().contains( - Integer.valueOf(columnIndex)); + boolean sorted = getSortingColumns().contains(Integer.valueOf(columnIndex)); if (!sorted) { return NONE; } @@ -115,5 +133,4 @@ public class NatTableComparatorChooser<T> extends this.isReverse = reverse; } } - -} +}
\ No newline at end of file |
