You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GridConnector.java 17KB

Migrate 7.7.5 branch patches to v8. (#7969) * Prevent adding several scrollbar handlers (#19189). Change-Id: Ib0cc6c6835aab6d263f153362a328bcf2be7bc5c * Prevent adding several scrollbar handlers (#19189). * Keep expand ratio for last row/column when reducing grid layout size (#20297) Change-Id: Iff53a803596f4fc1eae8e4bfa307b9c1f4df961a * Fixed drag and drop failure when message dragged from email client (#20451) When dragging message form email client on Windows, item.webkitGetAsEntry() might return null creating NPE on the client side. Added additional checks for this situation. Change-Id: I569f7e6d0d7b137f24be53d1fbce384695ae8c73 * Change expected pre-release version number pattern in publish report Change-Id: Icdacecc490d2490ea9e262f5c5736c1dece2a89d * Mark TextField/TextArea as busy when a text change event is pending (#20469) Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50 # Conflicts: # client/src/main/java/com/vaadin/client/ui/VTextField.java # uitest/src/main/java/com/vaadin/tests/components/textfield/TextChangeEvents.java * Fixed touch scrolling issue in Surface and WP devices (#18737) Fixed by using pointerevents instead of touchevents when the browser is IE11, or Edge. Also added touch-action: none; css rules into escalator.css to prevent default touch behaviour on IE11 and Edge. Does not affect IE8 to IE10 browsers, behaviour on those will stay the same as before the fix. No new unit tests since we do not have automatic touch testing possibilities yet. Please test manually with Surface: IE11 and Edge, use for example uitest: com.vaadin.tests.components.grid.basics.GridBasicsomponents.grid.basics.GridBasics Change-Id: Iddbf1852e6ffafc855f749d6f4ebb235ed0f5703 * Add lazy/simple resize mode to Grid (#20108) Change-Id: I47427efc28c350382dba8c1f50fd332a3f4585e4 # Conflicts: # client/src/main/java/com/vaadin/client/connectors/GridConnector.java # client/src/main/java/com/vaadin/client/widgets/Grid.java # server/src/main/java/com/vaadin/ui/Grid.java # shared/src/main/java/com/vaadin/shared/ui/grid/GridState.java # themes/src/main/themes/VAADIN/themes/base/grid/grid.scss # uitest/src/main/java/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java Change-Id: Ieca56121875198ed559a41c143b28926e2695433 * Fix NPE in case some items don't contain all properties of Grid. This could occur in when parent is a different entity than its children in hierarchical data. Change-Id: Icd53b5b5e5544a3680d0cd99702ab78224b2dc08 # Conflicts: # server/src/main/java/com/vaadin/data/fieldgroup/FieldGroup.java # server/src/main/java/com/vaadin/ui/Grid.java * Mark TextField/TextArea as busy when a text change event is pending (#20469) Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50 # Conflicts: # client/src/main/java/com/vaadin/client/ui/VTextField.java # uitest/src/test/java/com/vaadin/tests/components/textfield/TextChangeEventsTest.java * Add lazy/simple resize mode to Grid (#20108) Change-Id: I47427efc28c350382dba8c1f50fd332a3f4585e4 * Removed V8 VTextField unused import, forgotten @RunLocally. * Don't rely on selenium "sendKeys" behavior. * Revert "Change expected pre-release version number pattern in publish report" This reverts commit 8df27b952dddb691aead6a633c5b3724c98bf343. * Migrate TextField/TextArea patch from 7.7 to master (modern components) Mark TextField/TextArea as busy when a text change event is pending (#20469) Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50
7 years ago
Migrate 7.7.5 branch patches to v8. (#7969) * Prevent adding several scrollbar handlers (#19189). Change-Id: Ib0cc6c6835aab6d263f153362a328bcf2be7bc5c * Prevent adding several scrollbar handlers (#19189). * Keep expand ratio for last row/column when reducing grid layout size (#20297) Change-Id: Iff53a803596f4fc1eae8e4bfa307b9c1f4df961a * Fixed drag and drop failure when message dragged from email client (#20451) When dragging message form email client on Windows, item.webkitGetAsEntry() might return null creating NPE on the client side. Added additional checks for this situation. Change-Id: I569f7e6d0d7b137f24be53d1fbce384695ae8c73 * Change expected pre-release version number pattern in publish report Change-Id: Icdacecc490d2490ea9e262f5c5736c1dece2a89d * Mark TextField/TextArea as busy when a text change event is pending (#20469) Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50 # Conflicts: # client/src/main/java/com/vaadin/client/ui/VTextField.java # uitest/src/main/java/com/vaadin/tests/components/textfield/TextChangeEvents.java * Fixed touch scrolling issue in Surface and WP devices (#18737) Fixed by using pointerevents instead of touchevents when the browser is IE11, or Edge. Also added touch-action: none; css rules into escalator.css to prevent default touch behaviour on IE11 and Edge. Does not affect IE8 to IE10 browsers, behaviour on those will stay the same as before the fix. No new unit tests since we do not have automatic touch testing possibilities yet. Please test manually with Surface: IE11 and Edge, use for example uitest: com.vaadin.tests.components.grid.basics.GridBasicsomponents.grid.basics.GridBasics Change-Id: Iddbf1852e6ffafc855f749d6f4ebb235ed0f5703 * Add lazy/simple resize mode to Grid (#20108) Change-Id: I47427efc28c350382dba8c1f50fd332a3f4585e4 # Conflicts: # client/src/main/java/com/vaadin/client/connectors/GridConnector.java # client/src/main/java/com/vaadin/client/widgets/Grid.java # server/src/main/java/com/vaadin/ui/Grid.java # shared/src/main/java/com/vaadin/shared/ui/grid/GridState.java # themes/src/main/themes/VAADIN/themes/base/grid/grid.scss # uitest/src/main/java/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java Change-Id: Ieca56121875198ed559a41c143b28926e2695433 * Fix NPE in case some items don't contain all properties of Grid. This could occur in when parent is a different entity than its children in hierarchical data. Change-Id: Icd53b5b5e5544a3680d0cd99702ab78224b2dc08 # Conflicts: # server/src/main/java/com/vaadin/data/fieldgroup/FieldGroup.java # server/src/main/java/com/vaadin/ui/Grid.java * Mark TextField/TextArea as busy when a text change event is pending (#20469) Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50 # Conflicts: # client/src/main/java/com/vaadin/client/ui/VTextField.java # uitest/src/test/java/com/vaadin/tests/components/textfield/TextChangeEventsTest.java * Add lazy/simple resize mode to Grid (#20108) Change-Id: I47427efc28c350382dba8c1f50fd332a3f4585e4 * Removed V8 VTextField unused import, forgotten @RunLocally. * Don't rely on selenium "sendKeys" behavior. * Revert "Change expected pre-release version number pattern in publish report" This reverts commit 8df27b952dddb691aead6a633c5b3724c98bf343. * Migrate TextField/TextArea patch from 7.7 to master (modern components) Mark TextField/TextArea as busy when a text change event is pending (#20469) Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50
7 years ago
Migrate 7.7.5 branch patches to v8. (#7969) * Prevent adding several scrollbar handlers (#19189). Change-Id: Ib0cc6c6835aab6d263f153362a328bcf2be7bc5c * Prevent adding several scrollbar handlers (#19189). * Keep expand ratio for last row/column when reducing grid layout size (#20297) Change-Id: Iff53a803596f4fc1eae8e4bfa307b9c1f4df961a * Fixed drag and drop failure when message dragged from email client (#20451) When dragging message form email client on Windows, item.webkitGetAsEntry() might return null creating NPE on the client side. Added additional checks for this situation. Change-Id: I569f7e6d0d7b137f24be53d1fbce384695ae8c73 * Change expected pre-release version number pattern in publish report Change-Id: Icdacecc490d2490ea9e262f5c5736c1dece2a89d * Mark TextField/TextArea as busy when a text change event is pending (#20469) Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50 # Conflicts: # client/src/main/java/com/vaadin/client/ui/VTextField.java # uitest/src/main/java/com/vaadin/tests/components/textfield/TextChangeEvents.java * Fixed touch scrolling issue in Surface and WP devices (#18737) Fixed by using pointerevents instead of touchevents when the browser is IE11, or Edge. Also added touch-action: none; css rules into escalator.css to prevent default touch behaviour on IE11 and Edge. Does not affect IE8 to IE10 browsers, behaviour on those will stay the same as before the fix. No new unit tests since we do not have automatic touch testing possibilities yet. Please test manually with Surface: IE11 and Edge, use for example uitest: com.vaadin.tests.components.grid.basics.GridBasicsomponents.grid.basics.GridBasics Change-Id: Iddbf1852e6ffafc855f749d6f4ebb235ed0f5703 * Add lazy/simple resize mode to Grid (#20108) Change-Id: I47427efc28c350382dba8c1f50fd332a3f4585e4 # Conflicts: # client/src/main/java/com/vaadin/client/connectors/GridConnector.java # client/src/main/java/com/vaadin/client/widgets/Grid.java # server/src/main/java/com/vaadin/ui/Grid.java # shared/src/main/java/com/vaadin/shared/ui/grid/GridState.java # themes/src/main/themes/VAADIN/themes/base/grid/grid.scss # uitest/src/main/java/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java Change-Id: Ieca56121875198ed559a41c143b28926e2695433 * Fix NPE in case some items don't contain all properties of Grid. This could occur in when parent is a different entity than its children in hierarchical data. Change-Id: Icd53b5b5e5544a3680d0cd99702ab78224b2dc08 # Conflicts: # server/src/main/java/com/vaadin/data/fieldgroup/FieldGroup.java # server/src/main/java/com/vaadin/ui/Grid.java * Mark TextField/TextArea as busy when a text change event is pending (#20469) Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50 # Conflicts: # client/src/main/java/com/vaadin/client/ui/VTextField.java # uitest/src/test/java/com/vaadin/tests/components/textfield/TextChangeEventsTest.java * Add lazy/simple resize mode to Grid (#20108) Change-Id: I47427efc28c350382dba8c1f50fd332a3f4585e4 * Removed V8 VTextField unused import, forgotten @RunLocally. * Don't rely on selenium "sendKeys" behavior. * Revert "Change expected pre-release version number pattern in publish report" This reverts commit 8df27b952dddb691aead6a633c5b3724c98bf343. * Migrate TextField/TextArea patch from 7.7 to master (modern components) Mark TextField/TextArea as busy when a text change event is pending (#20469) Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50
7 years ago
Migrate 7.7.5 branch patches to v8. (#7969) * Prevent adding several scrollbar handlers (#19189). Change-Id: Ib0cc6c6835aab6d263f153362a328bcf2be7bc5c * Prevent adding several scrollbar handlers (#19189). * Keep expand ratio for last row/column when reducing grid layout size (#20297) Change-Id: Iff53a803596f4fc1eae8e4bfa307b9c1f4df961a * Fixed drag and drop failure when message dragged from email client (#20451) When dragging message form email client on Windows, item.webkitGetAsEntry() might return null creating NPE on the client side. Added additional checks for this situation. Change-Id: I569f7e6d0d7b137f24be53d1fbce384695ae8c73 * Change expected pre-release version number pattern in publish report Change-Id: Icdacecc490d2490ea9e262f5c5736c1dece2a89d * Mark TextField/TextArea as busy when a text change event is pending (#20469) Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50 # Conflicts: # client/src/main/java/com/vaadin/client/ui/VTextField.java # uitest/src/main/java/com/vaadin/tests/components/textfield/TextChangeEvents.java * Fixed touch scrolling issue in Surface and WP devices (#18737) Fixed by using pointerevents instead of touchevents when the browser is IE11, or Edge. Also added touch-action: none; css rules into escalator.css to prevent default touch behaviour on IE11 and Edge. Does not affect IE8 to IE10 browsers, behaviour on those will stay the same as before the fix. No new unit tests since we do not have automatic touch testing possibilities yet. Please test manually with Surface: IE11 and Edge, use for example uitest: com.vaadin.tests.components.grid.basics.GridBasicsomponents.grid.basics.GridBasics Change-Id: Iddbf1852e6ffafc855f749d6f4ebb235ed0f5703 * Add lazy/simple resize mode to Grid (#20108) Change-Id: I47427efc28c350382dba8c1f50fd332a3f4585e4 # Conflicts: # client/src/main/java/com/vaadin/client/connectors/GridConnector.java # client/src/main/java/com/vaadin/client/widgets/Grid.java # server/src/main/java/com/vaadin/ui/Grid.java # shared/src/main/java/com/vaadin/shared/ui/grid/GridState.java # themes/src/main/themes/VAADIN/themes/base/grid/grid.scss # uitest/src/main/java/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java Change-Id: Ieca56121875198ed559a41c143b28926e2695433 * Fix NPE in case some items don't contain all properties of Grid. This could occur in when parent is a different entity than its children in hierarchical data. Change-Id: Icd53b5b5e5544a3680d0cd99702ab78224b2dc08 # Conflicts: # server/src/main/java/com/vaadin/data/fieldgroup/FieldGroup.java # server/src/main/java/com/vaadin/ui/Grid.java * Mark TextField/TextArea as busy when a text change event is pending (#20469) Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50 # Conflicts: # client/src/main/java/com/vaadin/client/ui/VTextField.java # uitest/src/test/java/com/vaadin/tests/components/textfield/TextChangeEventsTest.java * Add lazy/simple resize mode to Grid (#20108) Change-Id: I47427efc28c350382dba8c1f50fd332a3f4585e4 * Removed V8 VTextField unused import, forgotten @RunLocally. * Don't rely on selenium "sendKeys" behavior. * Revert "Change expected pre-release version number pattern in publish report" This reverts commit 8df27b952dddb691aead6a633c5b3724c98bf343. * Migrate TextField/TextArea patch from 7.7 to master (modern components) Mark TextField/TextArea as busy when a text change event is pending (#20469) Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50
7 years ago
Migrate 7.7.5 branch patches to v8. (#7969) * Prevent adding several scrollbar handlers (#19189). Change-Id: Ib0cc6c6835aab6d263f153362a328bcf2be7bc5c * Prevent adding several scrollbar handlers (#19189). * Keep expand ratio for last row/column when reducing grid layout size (#20297) Change-Id: Iff53a803596f4fc1eae8e4bfa307b9c1f4df961a * Fixed drag and drop failure when message dragged from email client (#20451) When dragging message form email client on Windows, item.webkitGetAsEntry() might return null creating NPE on the client side. Added additional checks for this situation. Change-Id: I569f7e6d0d7b137f24be53d1fbce384695ae8c73 * Change expected pre-release version number pattern in publish report Change-Id: Icdacecc490d2490ea9e262f5c5736c1dece2a89d * Mark TextField/TextArea as busy when a text change event is pending (#20469) Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50 # Conflicts: # client/src/main/java/com/vaadin/client/ui/VTextField.java # uitest/src/main/java/com/vaadin/tests/components/textfield/TextChangeEvents.java * Fixed touch scrolling issue in Surface and WP devices (#18737) Fixed by using pointerevents instead of touchevents when the browser is IE11, or Edge. Also added touch-action: none; css rules into escalator.css to prevent default touch behaviour on IE11 and Edge. Does not affect IE8 to IE10 browsers, behaviour on those will stay the same as before the fix. No new unit tests since we do not have automatic touch testing possibilities yet. Please test manually with Surface: IE11 and Edge, use for example uitest: com.vaadin.tests.components.grid.basics.GridBasicsomponents.grid.basics.GridBasics Change-Id: Iddbf1852e6ffafc855f749d6f4ebb235ed0f5703 * Add lazy/simple resize mode to Grid (#20108) Change-Id: I47427efc28c350382dba8c1f50fd332a3f4585e4 # Conflicts: # client/src/main/java/com/vaadin/client/connectors/GridConnector.java # client/src/main/java/com/vaadin/client/widgets/Grid.java # server/src/main/java/com/vaadin/ui/Grid.java # shared/src/main/java/com/vaadin/shared/ui/grid/GridState.java # themes/src/main/themes/VAADIN/themes/base/grid/grid.scss # uitest/src/main/java/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java Change-Id: Ieca56121875198ed559a41c143b28926e2695433 * Fix NPE in case some items don't contain all properties of Grid. This could occur in when parent is a different entity than its children in hierarchical data. Change-Id: Icd53b5b5e5544a3680d0cd99702ab78224b2dc08 # Conflicts: # server/src/main/java/com/vaadin/data/fieldgroup/FieldGroup.java # server/src/main/java/com/vaadin/ui/Grid.java * Mark TextField/TextArea as busy when a text change event is pending (#20469) Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50 # Conflicts: # client/src/main/java/com/vaadin/client/ui/VTextField.java # uitest/src/test/java/com/vaadin/tests/components/textfield/TextChangeEventsTest.java * Add lazy/simple resize mode to Grid (#20108) Change-Id: I47427efc28c350382dba8c1f50fd332a3f4585e4 * Removed V8 VTextField unused import, forgotten @RunLocally. * Don't rely on selenium "sendKeys" behavior. * Revert "Change expected pre-release version number pattern in publish report" This reverts commit 8df27b952dddb691aead6a633c5b3724c98bf343. * Migrate TextField/TextArea patch from 7.7 to master (modern components) Mark TextField/TextArea as busy when a text change event is pending (#20469) Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50
7 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. /*
  2. * Copyright 2000-2016 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.client.connectors.grid;
  17. import java.util.ArrayList;
  18. import java.util.Collections;
  19. import java.util.HashMap;
  20. import java.util.List;
  21. import java.util.Map;
  22. import java.util.Objects;
  23. import java.util.Set;
  24. import java.util.stream.Collectors;
  25. import com.google.gwt.dom.client.Element;
  26. import com.google.gwt.dom.client.EventTarget;
  27. import com.google.gwt.dom.client.NativeEvent;
  28. import com.google.gwt.event.shared.HandlerRegistration;
  29. import com.vaadin.client.ComponentConnector;
  30. import com.vaadin.client.ConnectorHierarchyChangeEvent;
  31. import com.vaadin.client.ConnectorHierarchyChangeEvent.ConnectorHierarchyChangeHandler;
  32. import com.vaadin.client.DeferredWorker;
  33. import com.vaadin.client.HasComponentsConnector;
  34. import com.vaadin.client.MouseEventDetailsBuilder;
  35. import com.vaadin.client.TooltipInfo;
  36. import com.vaadin.client.WidgetUtil;
  37. import com.vaadin.client.annotations.OnStateChange;
  38. import com.vaadin.client.connectors.AbstractListingConnector;
  39. import com.vaadin.client.connectors.grid.ColumnConnector.CustomColumn;
  40. import com.vaadin.client.data.DataSource;
  41. import com.vaadin.client.ui.SimpleManagedLayout;
  42. import com.vaadin.client.widget.grid.CellReference;
  43. import com.vaadin.client.widget.grid.EventCellReference;
  44. import com.vaadin.client.widget.grid.events.BodyClickHandler;
  45. import com.vaadin.client.widget.grid.events.BodyDoubleClickHandler;
  46. import com.vaadin.client.widget.grid.events.GridClickEvent;
  47. import com.vaadin.client.widget.grid.events.GridDoubleClickEvent;
  48. import com.vaadin.client.widget.grid.selection.ClickSelectHandler;
  49. import com.vaadin.client.widget.grid.selection.SpaceSelectHandler;
  50. import com.vaadin.client.widget.grid.sort.SortEvent;
  51. import com.vaadin.client.widget.grid.sort.SortOrder;
  52. import com.vaadin.client.widgets.Grid;
  53. import com.vaadin.client.widgets.Grid.Column;
  54. import com.vaadin.client.widgets.Grid.FooterRow;
  55. import com.vaadin.client.widgets.Grid.HeaderRow;
  56. import com.vaadin.shared.MouseEventDetails;
  57. import com.vaadin.shared.data.sort.SortDirection;
  58. import com.vaadin.shared.ui.Connect;
  59. import com.vaadin.shared.ui.grid.GridConstants;
  60. import com.vaadin.shared.ui.grid.GridConstants.Section;
  61. import com.vaadin.shared.ui.grid.GridServerRpc;
  62. import com.vaadin.shared.ui.grid.GridState;
  63. import com.vaadin.shared.ui.grid.SectionState;
  64. import com.vaadin.shared.ui.grid.SectionState.CellState;
  65. import com.vaadin.shared.ui.grid.SectionState.RowState;
  66. import elemental.json.JsonObject;
  67. /**
  68. * A connector class for the typed Grid component.
  69. *
  70. * @author Vaadin Ltd
  71. * @since 8.0
  72. */
  73. @Connect(com.vaadin.ui.Grid.class)
  74. public class GridConnector extends AbstractListingConnector
  75. implements HasComponentsConnector, SimpleManagedLayout, DeferredWorker {
  76. private class ItemClickHandler
  77. implements BodyClickHandler, BodyDoubleClickHandler {
  78. @Override
  79. public void onClick(GridClickEvent event) {
  80. if (hasEventListener(GridConstants.ITEM_CLICK_EVENT_ID)) {
  81. fireItemClick(event.getTargetCell(), event.getNativeEvent());
  82. }
  83. }
  84. @Override
  85. public void onDoubleClick(GridDoubleClickEvent event) {
  86. if (hasEventListener(GridConstants.ITEM_CLICK_EVENT_ID)) {
  87. fireItemClick(event.getTargetCell(), event.getNativeEvent());
  88. }
  89. }
  90. private void fireItemClick(CellReference<?> cell,
  91. NativeEvent mouseEvent) {
  92. String rowKey = getRowKey((JsonObject) cell.getRow());
  93. String columnId = columnToIdMap.get(cell.getColumn());
  94. getRpcProxy(GridServerRpc.class).itemClick(rowKey, columnId,
  95. MouseEventDetailsBuilder
  96. .buildMouseEventDetails(mouseEvent));
  97. }
  98. }
  99. /* Map to keep track of all added columns */
  100. private Map<CustomColumn, String> columnToIdMap = new HashMap<>();
  101. private Map<String, CustomColumn> idToColumn = new HashMap<>();
  102. /* Child component list for HasComponentsConnector */
  103. private List<ComponentConnector> childComponents;
  104. private SpaceSelectHandler<JsonObject> spaceSelectHandler;
  105. private ClickSelectHandler<JsonObject> clickSelectHandler;
  106. private ItemClickHandler itemClickHandler = new ItemClickHandler();
  107. /**
  108. * Gets the string identifier of the given column in this grid.
  109. *
  110. * @param column
  111. * the column whose id to get
  112. * @return the string id of the column
  113. */
  114. public String getColumnId(Column<?, ?> column) {
  115. return columnToIdMap.get(column);
  116. }
  117. /**
  118. * Gets the column corresponding to the given string identifier.
  119. *
  120. * @param columnId
  121. * the id of the column to get
  122. * @return the column with the given id
  123. */
  124. public CustomColumn getColumn(String columnId) {
  125. return idToColumn.get(columnId);
  126. }
  127. @Override
  128. @SuppressWarnings("unchecked")
  129. public Grid<JsonObject> getWidget() {
  130. return (Grid<JsonObject>) super.getWidget();
  131. }
  132. @Override
  133. protected void init() {
  134. super.init();
  135. // Default selection style is space key.
  136. spaceSelectHandler = new SpaceSelectHandler<>(getWidget());
  137. getWidget().addSortHandler(this::handleSortEvent);
  138. getWidget().setRowStyleGenerator(rowRef -> {
  139. JsonObject json = rowRef.getRow();
  140. return json.hasKey(GridState.JSONKEY_ROWSTYLE)
  141. ? json.getString(GridState.JSONKEY_ROWSTYLE) : null;
  142. });
  143. getWidget().setCellStyleGenerator(cellRef -> {
  144. JsonObject row = cellRef.getRow();
  145. if (!row.hasKey(GridState.JSONKEY_CELLSTYLES)) {
  146. return null;
  147. }
  148. Column<?, JsonObject> column = cellRef.getColumn();
  149. if (column instanceof CustomColumn) {
  150. String id = ((CustomColumn) column).getConnectorId();
  151. JsonObject cellStyles = row
  152. .getObject(GridState.JSONKEY_CELLSTYLES);
  153. if (cellStyles.hasKey(id)) {
  154. return cellStyles.getString(id);
  155. }
  156. }
  157. return null;
  158. });
  159. getWidget().addColumnVisibilityChangeHandler(event -> {
  160. if (event.isUserOriginated()) {
  161. getRpcProxy(GridServerRpc.class).columnVisibilityChanged(
  162. getColumnId(event.getColumn()), event.isHidden());
  163. }
  164. });
  165. getWidget().addColumnReorderHandler(event -> {
  166. if (event.isUserOriginated()) {
  167. List<String> newColumnOrder = mapColumnsToIds(
  168. event.getNewColumnOrder());
  169. List<String> oldColumnOrder = mapColumnsToIds(
  170. event.getOldColumnOrder());
  171. getRpcProxy(GridServerRpc.class)
  172. .columnsReordered(newColumnOrder, oldColumnOrder);
  173. }
  174. });
  175. getWidget().addColumnResizeHandler(event -> {
  176. Column<?, JsonObject> column = event.getColumn();
  177. getRpcProxy(GridServerRpc.class).columnResized(getColumnId(column),
  178. column.getWidthActual());
  179. });
  180. /* Item click events */
  181. getWidget().addBodyClickHandler(itemClickHandler);
  182. getWidget().addBodyDoubleClickHandler(itemClickHandler);
  183. layout();
  184. }
  185. @SuppressWarnings("unchecked")
  186. @OnStateChange("columnOrder")
  187. void updateColumnOrder() {
  188. getWidget().setColumnOrder(getState().columnOrder.stream()
  189. .map(this::getColumn).toArray(size -> new Column[size]));
  190. }
  191. @OnStateChange("columnResizeMode")
  192. void updateColumnResizeMode() {
  193. getWidget().setColumnResizeMode(getState().columnResizeMode);
  194. }
  195. /**
  196. * Updates the grid header section on state change.
  197. */
  198. @OnStateChange("header")
  199. void updateHeader() {
  200. final Grid<JsonObject> grid = getWidget();
  201. final SectionState state = getState().header;
  202. while (grid.getHeaderRowCount() > 0) {
  203. grid.removeHeaderRow(0);
  204. }
  205. for (RowState rowState : state.rows) {
  206. HeaderRow row = grid.appendHeaderRow();
  207. if (rowState.defaultHeader) {
  208. grid.setDefaultHeaderRow(row);
  209. }
  210. updateStaticRow(rowState, row);
  211. }
  212. }
  213. private void updateStaticRow(RowState rowState,
  214. Grid.StaticSection.StaticRow row) {
  215. rowState.cells.forEach((columnId, cellState) -> {
  216. updateStaticCellFromState(row.getCell(getColumn(columnId)),
  217. cellState);
  218. });
  219. for (Map.Entry<CellState, Set<String>> cellGroupEntry : rowState.cellGroups
  220. .entrySet()) {
  221. Set<String> group = cellGroupEntry.getValue();
  222. Grid.Column<?, ?>[] columns = group.stream().map(idToColumn::get)
  223. .toArray(size -> new Grid.Column<?, ?>[size]);
  224. // Set state to be the same as first in group.
  225. updateStaticCellFromState(row.join(columns),
  226. cellGroupEntry.getKey());
  227. }
  228. }
  229. private void updateStaticCellFromState(Grid.StaticSection.StaticCell cell,
  230. CellState cellState) {
  231. switch (cellState.type) {
  232. case TEXT:
  233. cell.setText(cellState.text);
  234. break;
  235. case HTML:
  236. cell.setHtml(cellState.html);
  237. break;
  238. case WIDGET:
  239. ComponentConnector connector = (ComponentConnector) cellState.connector;
  240. if (connector != null) {
  241. cell.setWidget(connector.getWidget());
  242. } else {
  243. // This happens if you do setVisible(false) on the component on
  244. // the server side
  245. cell.setWidget(null);
  246. }
  247. break;
  248. default:
  249. throw new IllegalStateException(
  250. "unexpected cell type: " + cellState.type);
  251. }
  252. cell.setStyleName(cellState.styleName);
  253. }
  254. /**
  255. * Updates the grid footer section on state change.
  256. */
  257. @OnStateChange("footer")
  258. void updateFooter() {
  259. final Grid<JsonObject> grid = getWidget();
  260. final SectionState state = getState().footer;
  261. while (grid.getFooterRowCount() > 0) {
  262. grid.removeFooterRow(0);
  263. }
  264. for (RowState rowState : state.rows) {
  265. FooterRow row = grid.appendFooterRow();
  266. updateStaticRow(rowState, row);
  267. }
  268. }
  269. @Override
  270. public void setDataSource(DataSource<JsonObject> dataSource) {
  271. super.setDataSource(dataSource);
  272. getWidget().setDataSource(dataSource);
  273. }
  274. /**
  275. * Adds a column to the Grid widget. For each column a communication id
  276. * stored for client to server communication.
  277. *
  278. * @param column
  279. * column to add
  280. * @param id
  281. * communication id
  282. */
  283. public void addColumn(CustomColumn column, String id) {
  284. assert !columnToIdMap.containsKey(column) && !columnToIdMap
  285. .containsValue(id) : "Column with given id already exists.";
  286. getWidget().addColumn(column);
  287. columnToIdMap.put(column, id);
  288. idToColumn.put(id, column);
  289. }
  290. /**
  291. * Removes a column from Grid widget. This method also removes communication
  292. * id mapping for the column.
  293. *
  294. * @param column
  295. * column to remove
  296. */
  297. public void removeColumn(CustomColumn column) {
  298. assert columnToIdMap
  299. .containsKey(column) : "Given Column does not exist.";
  300. getWidget().removeColumn(column);
  301. String id = columnToIdMap.remove(column);
  302. idToColumn.remove(id);
  303. }
  304. @Override
  305. public void onUnregister() {
  306. super.onUnregister();
  307. columnToIdMap.clear();
  308. removeClickHandler();
  309. if (spaceSelectHandler != null) {
  310. spaceSelectHandler.removeHandler();
  311. spaceSelectHandler = null;
  312. }
  313. }
  314. @Override
  315. public boolean isWorkPending() {
  316. return getWidget().isWorkPending();
  317. }
  318. @Override
  319. public void layout() {
  320. getWidget().onResize();
  321. }
  322. /**
  323. * Sends sort information from an event to the server-side of the Grid.
  324. *
  325. * @param event
  326. * the sort event
  327. */
  328. private void handleSortEvent(SortEvent<JsonObject> event) {
  329. List<String> columnIds = new ArrayList<>();
  330. List<SortDirection> sortDirections = new ArrayList<>();
  331. for (SortOrder so : event.getOrder()) {
  332. if (columnToIdMap.containsKey(so.getColumn())) {
  333. columnIds.add(columnToIdMap.get(so.getColumn()));
  334. sortDirections.add(so.getDirection());
  335. }
  336. }
  337. getRpcProxy(GridServerRpc.class).sort(columnIds.toArray(new String[0]),
  338. sortDirections.toArray(new SortDirection[0]),
  339. event.isUserOriginated());
  340. }
  341. /* HasComponentsConnector */
  342. @Override
  343. public void updateCaption(ComponentConnector connector) {
  344. // Details components don't support captions.
  345. }
  346. @Override
  347. public List<ComponentConnector> getChildComponents() {
  348. if (childComponents == null) {
  349. return Collections.emptyList();
  350. }
  351. return childComponents;
  352. }
  353. @Override
  354. public void setChildComponents(List<ComponentConnector> children) {
  355. childComponents = children;
  356. }
  357. @Override
  358. public HandlerRegistration addConnectorHierarchyChangeHandler(
  359. ConnectorHierarchyChangeHandler handler) {
  360. return ensureHandlerManager()
  361. .addHandler(ConnectorHierarchyChangeEvent.TYPE, handler);
  362. }
  363. @Override
  364. public GridState getState() {
  365. return (GridState) super.getState();
  366. }
  367. private void removeClickHandler() {
  368. if (clickSelectHandler != null) {
  369. clickSelectHandler.removeHandler();
  370. clickSelectHandler = null;
  371. }
  372. }
  373. @Override
  374. public boolean hasTooltip() {
  375. // Always check for generated descriptions.
  376. return true;
  377. }
  378. @Override
  379. public TooltipInfo getTooltipInfo(Element element) {
  380. CellReference<JsonObject> cell = getWidget().getCellReference(element);
  381. if (cell != null) {
  382. JsonObject row = cell.getRow();
  383. if (row != null && (row.hasKey(GridState.JSONKEY_ROWDESCRIPTION)
  384. || row.hasKey(GridState.JSONKEY_CELLDESCRIPTION))) {
  385. Column<?, JsonObject> column = cell.getColumn();
  386. if (column instanceof CustomColumn) {
  387. JsonObject cellDescriptions = row
  388. .getObject(GridState.JSONKEY_CELLDESCRIPTION);
  389. String id = ((CustomColumn) column).getConnectorId();
  390. if (cellDescriptions != null
  391. && cellDescriptions.hasKey(id)) {
  392. return new TooltipInfo(cellDescriptions.getString(id));
  393. } else if (row.hasKey(GridState.JSONKEY_ROWDESCRIPTION)) {
  394. return new TooltipInfo(row
  395. .getString(GridState.JSONKEY_ROWDESCRIPTION));
  396. }
  397. }
  398. }
  399. }
  400. if (super.hasTooltip()) {
  401. return super.getTooltipInfo(element);
  402. } else {
  403. return null;
  404. }
  405. }
  406. @Override
  407. protected void sendContextClickEvent(MouseEventDetails details,
  408. EventTarget eventTarget) {
  409. // if element is the resize indicator, ignore the event
  410. if (isResizeHandle(eventTarget)) {
  411. WidgetUtil.clearTextSelection();
  412. return;
  413. }
  414. EventCellReference<JsonObject> eventCell = getWidget().getEventCell();
  415. Section section = eventCell.getSection();
  416. String rowKey = null;
  417. if (eventCell.isBody() && eventCell.getRow() != null) {
  418. rowKey = getRowKey(eventCell.getRow());
  419. }
  420. String columnId = getColumnId(eventCell.getColumn());
  421. getRpcProxy(GridServerRpc.class).contextClick(eventCell.getRowIndex(),
  422. rowKey, columnId, section, details);
  423. WidgetUtil.clearTextSelection();
  424. }
  425. private boolean isResizeHandle(EventTarget eventTarget) {
  426. if (Element.is(eventTarget)) {
  427. Element e = Element.as(eventTarget);
  428. if (e.getClassName().contains("-column-resize-handle")) {
  429. return true;
  430. }
  431. }
  432. return false;
  433. }
  434. private List<String> mapColumnsToIds(List<Column<?, JsonObject>> columns) {
  435. return columns.stream().map(this::getColumnId).filter(Objects::nonNull)
  436. .collect(Collectors.toList());
  437. }
  438. }