summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/src/com/vaadin/client/ui/grid/Grid.java56
-rw-r--r--client/src/com/vaadin/client/ui/grid/sort/SortOrder.java20
-rw-r--r--shared/src/com/vaadin/shared/ui/grid/SortDirection.java21
-rw-r--r--uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSortingTest.java69
4 files changed, 159 insertions, 7 deletions
diff --git a/client/src/com/vaadin/client/ui/grid/Grid.java b/client/src/com/vaadin/client/ui/grid/Grid.java
index aa5215bef8..34bff2fd45 100644
--- a/client/src/com/vaadin/client/ui/grid/Grid.java
+++ b/client/src/com/vaadin/client/ui/grid/Grid.java
@@ -1265,6 +1265,50 @@ public class Grid<T> extends Composite implements
sinkEvents(getHeader().getConsumedEvents());
sinkEvents(Arrays.asList(BrowserEvents.KEYDOWN, BrowserEvents.KEYUP,
BrowserEvents.KEYPRESS));
+
+ // Make ENTER and SHIFT+ENTER in the header perform sorting
+ addKeyUpHandler(new HeaderKeyUpHandler() {
+ @Override
+ public void onKeyUp(GridKeyUpEvent event) {
+ if (event.getNativeKeyCode() != KeyCodes.KEY_ENTER) {
+ return;
+ }
+
+ final Cell cell = event.getActiveCell();
+ final GridColumn<?, T> column = columns.get(cell.getColumn());
+
+ // If SHIFT is down, we modify multi-sorting order
+ if (event.isShiftKeyDown() && sortOrder != null) {
+
+ final SortOrder so = getSortOrder(column);
+
+ if (so != null) {
+ // Flip sort direction in-place
+ final int idx = sortOrder.indexOf(so);
+ sortOrder.set(idx, so.getOpposite());
+ } else {
+ // Add a new sort rule to the end of the list
+ sortOrder.add(new SortOrder(column));
+ }
+
+ } else {
+ if (sortOrder.size() == 1
+ && sortOrder.get(0).getColumn() == column) {
+
+ // Reverse the sort order and re-sort
+ sortOrder.set(0, sortOrder.get(0).getOpposite());
+ } else {
+
+ // Manually re-set the sorting order
+ sortOrder.clear();
+ sortOrder.add(new SortOrder(column));
+ }
+ }
+
+ // We've modified the sort order, re-sort it now.
+ setSortOrder(sortOrder, SortEventOriginator.USER);
+ }
+ });
}
@Override
@@ -2083,8 +2127,8 @@ public class Grid<T> extends Composite implements
private Point rowEventTouchStartingPoint;
- private boolean handleHeaderDefaultRowEvent(Event event, RowContainer container,
- final Cell cell) {
+ private boolean handleHeaderDefaultRowEvent(Event event,
+ RowContainer container, final Cell cell) {
if (container != escalator.getHeader()) {
return false;
}
@@ -2488,9 +2532,11 @@ public class Grid<T> extends Composite implements
private void setSortOrder(List<SortOrder> order,
SortEventOriginator originator) {
- sortOrder.clear();
- if (order != null) {
- sortOrder.addAll(order);
+ if (order != sortOrder) {
+ sortOrder.clear();
+ if (order != null) {
+ sortOrder.addAll(order);
+ }
}
sort(originator);
}
diff --git a/client/src/com/vaadin/client/ui/grid/sort/SortOrder.java b/client/src/com/vaadin/client/ui/grid/sort/SortOrder.java
index 682beda793..8878e18872 100644
--- a/client/src/com/vaadin/client/ui/grid/sort/SortOrder.java
+++ b/client/src/com/vaadin/client/ui/grid/sort/SortOrder.java
@@ -32,6 +32,17 @@ public class SortOrder {
private final SortDirection direction;
/**
+ * Create a sort order descriptor with a default sorting direction value of
+ * {@link SortDirection#ASCENDING}.
+ *
+ * @param column
+ * a grid column descriptor object
+ */
+ public SortOrder(GridColumn<?, ?> column) {
+ this(column, SortDirection.ASCENDING);
+ }
+
+ /**
* Create a sort order descriptor.
*
* @param column
@@ -69,4 +80,13 @@ public class SortOrder {
public SortDirection getDirection() {
return direction;
}
+
+ /**
+ * Returns a new SortOrder object with the sort direction reversed.
+ *
+ * @return a new sort order object
+ */
+ public SortOrder getOpposite() {
+ return new SortOrder(column, direction.getOpposite());
+ }
}
diff --git a/shared/src/com/vaadin/shared/ui/grid/SortDirection.java b/shared/src/com/vaadin/shared/ui/grid/SortDirection.java
index 0b4eafc37f..9aed268d01 100644
--- a/shared/src/com/vaadin/shared/ui/grid/SortDirection.java
+++ b/shared/src/com/vaadin/shared/ui/grid/SortDirection.java
@@ -28,10 +28,27 @@ public enum SortDirection implements Serializable {
/**
* Ascending (e.g. A-Z, 1..9) sort order
*/
- ASCENDING,
+ ASCENDING {
+ @Override
+ public SortDirection getOpposite() {
+ return DESCENDING;
+ }
+ },
/**
* Descending (e.g. Z-A, 9..1) sort order
*/
- DESCENDING
+ DESCENDING {
+ @Override
+ public SortDirection getOpposite() {
+ return ASCENDING;
+ }
+ };
+
+ /**
+ * Get the sort direction that is the direct opposite to this one.
+ *
+ * @return a sort direction value
+ */
+ public abstract SortDirection getOpposite();
}
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSortingTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSortingTest.java
index 024be65e83..74a5c6ed95 100644
--- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSortingTest.java
+++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSortingTest.java
@@ -191,6 +191,75 @@ public class GridSortingTest extends GridBasicFeaturesTest {
}
+ private void sendKeys(CharSequence... seq) {
+ new Actions(getDriver()).sendKeys(seq).perform();
+ }
+
+ private void holdKey(Keys key) {
+ new Actions(getDriver()).keyDown(key).perform();
+ }
+
+ private void releaseKey(Keys key) {
+ new Actions(getDriver()).keyUp(key).perform();
+ }
+
+ private void assertLog(String expected) {
+ assertEquals(expected, getLogRow(0));
+ }
+
+ @Test
+ public void testKeyboardMultiColumnSorting() throws InterruptedException {
+ openTestURL();
+
+ //
+ // NOTE: This is a work-around to get the focus to the first header
+ // cell.
+ // We can't use element.focus() because TestBench (or, rather, Selenium
+ // beneath it) has rather interesting bugs regarding focus handling.
+ //
+ getGridElement().getCell(0, 0).click();
+ sendKeys(Keys.ARROW_UP);
+
+ // Sort ASCENDING on first column
+ sendKeys(Keys.ENTER);
+ assertLog("2. Sort order: [Column 0 ASCENDING] by USER");
+
+ // Move to next column
+ sendKeys(Keys.RIGHT);
+
+ // Add this column to the existing sorting group
+ holdKey(Keys.SHIFT);
+ sendKeys(Keys.ENTER);
+ releaseKey(Keys.SHIFT);
+ assertLog("4. Sort order: [Column 0 ASCENDING, Column 1 ASCENDING] by USER");
+
+ // Move to next column
+ sendKeys(Keys.RIGHT);
+
+ // Add a third column to the sorting group
+ holdKey(Keys.SHIFT);
+ sendKeys(Keys.ENTER);
+ releaseKey(Keys.SHIFT);
+ assertLog("6. Sort order: [Column 0 ASCENDING, Column 1 ASCENDING, Column 2 ASCENDING] by USER");
+
+ // Move back to the second column
+ sendKeys(Keys.LEFT);
+
+ // Change sort direction of the second column to DESCENDING
+ holdKey(Keys.SHIFT);
+ sendKeys(Keys.ENTER);
+ releaseKey(Keys.SHIFT);
+ assertLog("8. Sort order: [Column 0 ASCENDING, Column 1 DESCENDING, Column 2 ASCENDING] by USER");
+
+ // Move back to the third column
+ sendKeys(Keys.RIGHT);
+
+ // Reset sorting to third column, ASCENDING
+ sendKeys(Keys.ENTER);
+ assertLog("10. Sort order: [Column 2 ASCENDING] by USER");
+
+ }
+
private void sortBy(String column) {
selectMenuPath("Component", "State", "Sort by column", column);
}