diff options
author | Teemu Suo-Anttila <teemusa@vaadin.com> | 2017-03-01 14:27:49 +0200 |
---|---|---|
committer | Henri Sara <henri.sara@gmail.com> | 2017-03-07 12:36:54 +0200 |
commit | f5c15b9b2bcc4eeef210a5977449c76f3b952209 (patch) | |
tree | 6358ed330e0d2baa68d8cdbc5bc5f3893406f236 /compatibility-client | |
parent | 0cfb20938f2b15767ebbd367ad8312642b947c8c (diff) | |
download | vaadin-framework-f5c15b9b2bcc4eeef210a5977449c76f3b952209.tar.gz vaadin-framework-f5c15b9b2bcc4eeef210a5977449c76f3b952209.zip |
Synchronize code between V7 and compatibility package
Diffstat (limited to 'compatibility-client')
31 files changed, 636 insertions, 236 deletions
diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/AbstractRendererConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/AbstractRendererConnector.java index 284cc225e0..fe0c561d5c 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/AbstractRendererConnector.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/AbstractRendererConnector.java @@ -124,5 +124,4 @@ public abstract class AbstractRendererConnector<T> protected void extend(ServerConnector target) { // NOOP } - } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/GridConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/GridConnector.java index c59ec0afe4..87a4c90360 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/GridConnector.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/GridConnector.java @@ -153,7 +153,7 @@ public class GridConnector extends AbstractHasComponentsConnector } /** - * Custom implementation of the custom grid column using a JSONObject to + * Custom implementation of the custom grid column using a JSONObject to * represent the cell value and String as a column type. */ private class CustomGridColumn extends Grid.Column<Object, JsonObject> { diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/JavaScriptRendererConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/JavaScriptRendererConnector.java index 6a94416ad9..51071e2c50 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/JavaScriptRendererConnector.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/JavaScriptRendererConnector.java @@ -17,6 +17,7 @@ package com.vaadin.v7.client.connectors; import java.util.ArrayList; import java.util.Collection; +import java.util.logging.Logger; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArrayString; @@ -135,8 +136,16 @@ public class JavaScriptRendererConnector + " must have a function named 'render'"); } + if (hasFunction("destory")) { + getLogger().severe("Your JavaScript connector (" + + helper.getInitFunctionName() + + ") has a typo. The destory method should be renamed to destroy."); + + } + final boolean hasInit = hasFunction("init"); - final boolean hasDestroy = hasFunction("destroy"); + final boolean hasDestroy = hasFunction("destroy") + || hasFunction("destory"); final boolean hasOnActivate = hasFunction("onActivate"); final boolean hasGetConsumedEvents = hasFunction("getConsumedEvents"); final boolean hasOnBrowserEvent = hasFunction("onBrowserEvent"); @@ -183,16 +192,20 @@ public class JavaScriptRendererConnector @Override public void destroy(RendererCellReference cell) { if (hasDestroy) { - destory(helper.getConnectorWrapper(), getJsCell(cell)); + destroy(helper.getConnectorWrapper(), getJsCell(cell)); } else { super.destroy(cell); } } - private native void destory(JavaScriptObject wrapper, + private native void destroy(JavaScriptObject wrapper, JavaScriptObject cell) /*-{ - wrapper.destory(cell); + if (wrapper.destroy) { + wrapper.destroy(cell); + } else { + wrapper.destory(cell); + } }-*/; @Override @@ -258,6 +271,10 @@ public class JavaScriptRendererConnector }; } + private Logger getLogger() { + return Logger.getLogger(JavaScriptRendererConnector.class.getName()); + } + @Override public Object decode(JsonValue value) { // Let the js logic decode the raw json that the server sent diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/MultiSelectionModelConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/MultiSelectionModelConnector.java index 5103abb285..035498db61 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/MultiSelectionModelConnector.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/MultiSelectionModelConnector.java @@ -22,6 +22,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.logging.Logger; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.ui.CheckBox; @@ -37,12 +38,15 @@ import com.vaadin.v7.client.widget.grid.DataAvailableEvent; import com.vaadin.v7.client.widget.grid.DataAvailableHandler; import com.vaadin.v7.client.widget.grid.events.SelectAllEvent; import com.vaadin.v7.client.widget.grid.events.SelectAllHandler; +import com.vaadin.v7.client.widget.grid.selection.HasUserSelectionAllowed; import com.vaadin.v7.client.widget.grid.selection.MultiSelectionRenderer; import com.vaadin.v7.client.widget.grid.selection.SelectionModel; import com.vaadin.v7.client.widget.grid.selection.SelectionModel.Multi; import com.vaadin.v7.client.widget.grid.selection.SpaceSelectHandler; import com.vaadin.v7.client.widgets.Grid; +import com.vaadin.v7.client.widgets.Grid.Column; import com.vaadin.v7.client.widgets.Grid.HeaderCell; +import com.vaadin.v7.client.widgets.Grid.SelectionColumn; import com.vaadin.v7.shared.ui.grid.GridState; import com.vaadin.v7.shared.ui.grid.selection.MultiSelectionModelServerRpc; import com.vaadin.v7.shared.ui.grid.selection.MultiSelectionModelState; @@ -94,8 +98,30 @@ public class MultiSelectionModelConnector extends } } + @OnStateChange("userSelectionAllowed") + void updateUserSelectionAllowed() { + if (selectionModel instanceof HasUserSelectionAllowed) { + ((HasUserSelectionAllowed) selectionModel) + .setUserSelectionAllowed(getState().userSelectionAllowed); + } else { + getLogger().warning("userSelectionAllowed set to " + + getState().userSelectionAllowed + + " but the selection model does not implement " + + HasUserSelectionAllowed.class.getSimpleName()); + } + } + + private static Logger getLogger() { + return Logger.getLogger(MultiSelectionModelConnector.class.getName()); + } + + /** + * The default multi selection model used for this connector. + * + */ protected class MultiSelectionModel extends AbstractSelectionModel - implements SelectionModel.Multi.Batched<JsonObject> { + implements SelectionModel.Multi.Batched<JsonObject>, + HasUserSelectionAllowed<JsonObject> { private ComplexRenderer<Boolean> renderer = null; private Set<RowHandle<JsonObject>> selected = new HashSet<RowHandle<JsonObject>>(); @@ -104,6 +130,7 @@ public class MultiSelectionModelConnector extends private HandlerRegistration dataAvailable; private Range availableRows; private boolean batchSelect = false; + private boolean userSelectionAllowed = true; @Override public void setGrid(Grid<JsonObject> grid) { @@ -382,5 +409,21 @@ public class MultiSelectionModelConnector extends public Collection<JsonObject> getDeselectedRowsBatch() { return Collections.unmodifiableSet(getRows(deselected)); } + + @Override + public boolean isUserSelectionAllowed() { + return userSelectionAllowed; + } + + @Override + public void setUserSelectionAllowed(boolean userSelectionAllowed) { + this.userSelectionAllowed = userSelectionAllowed; + for (Column<?, JsonObject> c : getGrid().getColumns()) { + if (c instanceof SelectionColumn) { + ((SelectionColumn) c) + .setUserSelectionAllowed(userSelectionAllowed); + } + } + } } } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/SingleSelectionModelConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/SingleSelectionModelConnector.java index 059278c311..d922166451 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/SingleSelectionModelConnector.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/SingleSelectionModelConnector.java @@ -15,12 +15,15 @@ */ package com.vaadin.v7.client.connectors; +import java.util.logging.Logger; + import com.vaadin.client.ServerConnector; import com.vaadin.client.annotations.OnStateChange; import com.vaadin.client.data.DataSource.RowHandle; import com.vaadin.shared.ui.Connect; import com.vaadin.v7.client.renderers.Renderer; import com.vaadin.v7.client.widget.grid.selection.ClickSelectHandler; +import com.vaadin.v7.client.widget.grid.selection.HasUserSelectionAllowed; import com.vaadin.v7.client.widget.grid.selection.SelectionModel; import com.vaadin.v7.client.widget.grid.selection.SelectionModel.Single; import com.vaadin.v7.client.widget.grid.selection.SpaceSelectHandler; @@ -75,14 +78,34 @@ public class SingleSelectionModelConnector extends selectionModel.setDeselectAllowed(getState().deselectAllowed); } + @OnStateChange("userSelectionAllowed") + void updateUserSelectionAllowed() { + + if (selectionModel instanceof HasUserSelectionAllowed) { + ((HasUserSelectionAllowed) selectionModel) + .setUserSelectionAllowed(getState().userSelectionAllowed); + } else { + getLogger().warning("userSelectionAllowed set to " + + getState().userSelectionAllowed + + " but the selection model does not implement " + + HasUserSelectionAllowed.class.getSimpleName()); + } + } + + private static Logger getLogger() { + return Logger.getLogger(SingleSelectionModelConnector.class.getName()); + } + /** * SingleSelectionModel without a selection column renderer. */ public class SingleSelectionModel extends AbstractSelectionModel - implements SelectionModel.Single<JsonObject> { + implements SelectionModel.Single<JsonObject>, + HasUserSelectionAllowed<JsonObject> { private RowHandle<JsonObject> selectedRow; private boolean deselectAllowed; + private boolean userSelectionAllowed = true; @Override public Renderer<Boolean> getSelectionColumnRenderer() { @@ -153,8 +176,14 @@ public class SingleSelectionModelConnector extends @Override public boolean deselect(JsonObject row) { - if (getRowHandle(row).equals(selectedRow)) { - select(null); + if (isSelected(row)) { + // If no selection has happened client side, then selectedRow is + // null but must be set so that a deselection event with the + // correct key can be sent to the server + selectedRow = getRowHandle(row); + selectedRow.pin(); + + return select(null); } return false; } @@ -176,5 +205,15 @@ public class SingleSelectionModelConnector extends public boolean isDeselectAllowed() { return deselectAllowed; } + + @Override + public boolean isUserSelectionAllowed() { + return userSelectionAllowed; + } + + @Override + public void setUserSelectionAllowed(boolean userSelectionAllowed) { + this.userSelectionAllowed = userSelectionAllowed; + } } -}
\ No newline at end of file +} diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/renderers/ImageRenderer.java b/compatibility-client/src/main/java/com/vaadin/v7/client/renderers/ImageRenderer.java index a29b4f2cfd..a151d3ff68 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/renderers/ImageRenderer.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/renderers/ImageRenderer.java @@ -29,7 +29,7 @@ import com.vaadin.v7.client.widget.grid.RendererCellReference; */ public class ImageRenderer extends ClickableRenderer<String, Image> { - public static final String TRANSPARENT_GIF_1PX = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs="; + public static final String TRANSPARENT_GIF_1PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"; @Override public Image createWidget() { diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VCalendarPanel.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VCalendarPanel.java index a27f2c80cd..8780c980ab 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VCalendarPanel.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VCalendarPanel.java @@ -1677,7 +1677,7 @@ public class VCalendarPanel extends FocusableFlexTable implements private ListBox createListBox() { ListBox lb = new ListBox(); - lb.setStyleName("v-select"); + lb.setStyleName(VNativeSelect.CLASSNAME); lb.addChangeHandler(this); lb.addBlurHandler(VCalendarPanel.this); lb.addFocusHandler(VCalendarPanel.this); diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VFilterSelect.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VFilterSelect.java index aa47481e6a..0daaff47f9 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VFilterSelect.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VFilterSelect.java @@ -1450,7 +1450,10 @@ public class VFilterSelect extends Composite }; private class IconWidget extends Widget { + private Icon icon; + IconWidget(Icon icon) { + this.icon = icon; setElement(icon.getElement()); addDomHandler(VFilterSelect.this, ClickEvent.getType()); } @@ -1908,25 +1911,59 @@ public class VFilterSelect extends Composite afterSelectedItemIconChange(); } } else { + IconWidget newIcon = new IconWidget(client.getIcon(iconUri)); + if (iconEquals(newIcon, selectedItemIcon)) { + /* + * Do not update the icon if nothing has changed. Otherwise we + * can cause problems such as not being able to click in the + * icon to open the popup (blur might occur and call this + * method, icon is replaced and the click event is not delivered + * to the new icon) + */ + return; + } + if (selectedItemIcon != null) { panel.remove(selectedItemIcon); } - selectedItemIcon = new IconWidget(client.getIcon(iconUri)); + // Older IE versions don't scale icon correctly if DOM // contains height and width attributes. - selectedItemIcon.getElement().removeAttribute("height"); - selectedItemIcon.getElement().removeAttribute("width"); - selectedItemIcon.addDomHandler(new LoadHandler() { + newIcon.getElement().removeAttribute("height"); + newIcon.getElement().removeAttribute("width"); + newIcon.addDomHandler(new LoadHandler() { @Override public void onLoad(LoadEvent event) { afterSelectedItemIconChange(); } }, LoadEvent.getType()); - panel.insert(selectedItemIcon, 0); + panel.insert(newIcon, 0); + selectedItemIcon = newIcon; afterSelectedItemIconChange(); } } + /** + * Checks if the icon widgets show the same icon. + * + * @param icon1 + * the first widget + * @param icon2 + * the second widget + * @return <code>true</code> if they show the same icon, <code>false</code> + * otherwise + */ + private static boolean iconEquals(IconWidget icon1, IconWidget icon2) { + if (icon1 == null) { + return icon2 == null; + } else if (icon2 == null) { + return false; + } else { + return icon1.icon.getUri().equals(icon2.icon.getUri()); + } + + } + private void afterSelectedItemIconChange() { if (BrowserInfo.get().isWebkit() || BrowserInfo.get().isIE8()) { // Some browsers need a nudge to reposition the text field @@ -2392,6 +2429,7 @@ public class VFilterSelect extends Composite } } else if (currentSuggestion != null) { setPromptingOff(currentSuggestion.caption); + setSelectedItemIcon(currentSuggestion.getIconUri()); } } removeStyleDependentName("focus"); diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VLabel.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VLabel.java index ebe28c0d31..6022135d90 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VLabel.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VLabel.java @@ -57,4 +57,5 @@ public class VLabel extends HTML { } } + // Vaadin 8 does not support IE8, no override for setText } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VOptionGroupBase.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VOptionGroupBase.java index 94a92e2980..239e6ff53a 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VOptionGroupBase.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VOptionGroupBase.java @@ -60,6 +60,8 @@ public abstract class VOptionGroupBase extends Composite implements Field, private boolean readonly; + // Intentional removal of cols in compatibility package + /** For internal use only. May be removed or replaced in the future. */ public int rows = 0; @@ -134,6 +136,8 @@ public abstract class VOptionGroupBase extends Composite implements Field, return nullSelectionItemAvailable; } + // Intentional removal of getColumns in compatibility package + /** * For internal use only. May be removed or replaced in the future. * diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VPopupCalendar.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VPopupCalendar.java index 832c03e99c..e93ce4c04c 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VPopupCalendar.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VPopupCalendar.java @@ -62,8 +62,7 @@ import com.vaadin.v7.shared.ui.datefield.Resolution; * selector. * * <b>Note:</b> To change the keyboard assignments used in the popup dialog you - * should extend <code>com.vaadin.v7.client.ui.VCalendarPanel</code> and then - * pass set it by calling the + * should extend <code>VCalendarPanel</code> and then pass set it by calling the * <code>setCalendarPanel(VCalendarPanel panel)</code> method. * */ @@ -270,9 +269,9 @@ public class VPopupCalendar extends VTextualDate * Sets the state of the text field of this component. By default the text * field is enabled. Disabling it causes only the button for date selection * to be active, thus preventing the user from entering invalid dates. See - * {@link http://dev.vaadin.com/ticket/6790}. + * <a href="http://dev.vaadin.com/ticket/6790">6790</a>. * - * @param state + * @param textFieldEnabled */ public void setTextFieldEnabled(boolean textFieldEnabled) { this.textFieldEnabled = textFieldEnabled; @@ -366,12 +365,6 @@ public class VPopupCalendar extends VTextualDate } } - /* - * (non-Javadoc) - * - * @see - * com.google.gwt.user.client.ui.UIObject#setStyleName(java.lang.String) - */ @Override public void setStyleName(String style) { super.setStyleName(style); @@ -419,13 +412,6 @@ public class VPopupCalendar extends VTextualDate } } - /* - * (non-Javadoc) - * - * @see - * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event - * .dom.client.ClickEvent) - */ @Override public void onClick(ClickEvent event) { if (event.getSource() == calendarToggle && isEnabled()) { @@ -438,13 +424,6 @@ public class VPopupCalendar extends VTextualDate } } - /* - * (non-Javadoc) - * - * @see - * com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google.gwt - * .event.logical.shared.CloseEvent) - */ @Override public void onClose(CloseEvent<PopupPanel> event) { if (event.getSource() == popup) { @@ -531,12 +510,6 @@ public class VPopupCalendar extends VTextualDate buildDate(); } - /* - * (non-Javadoc) - * - * @see com.vaadin.client.ui.VDateField#onBrowserEvent(com.google - * .gwt.user.client.Event) - */ @Override public void onBrowserEvent(com.google.gwt.user.client.Event event) { super.onBrowserEvent(event); @@ -617,7 +590,7 @@ public class VPopupCalendar extends VTextualDate * and it depends on the current resolution, what is considered inside the * range. * - * @param startDate + * @param rangeStart * - the allowed range's start date */ public void setRangeStart(Date rangeStart) { @@ -628,7 +601,7 @@ public class VPopupCalendar extends VTextualDate * Sets the end range for this component. The end range is inclusive, and it * depends on the current resolution, what is considered inside the range. * - * @param endDate + * @param rangeEnd * - the allowed range's end date */ public void setRangeEnd(Date rangeEnd) { diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VScrollTable.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VScrollTable.java index a6be4dc61a..3affa940fc 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VScrollTable.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VScrollTable.java @@ -3665,6 +3665,7 @@ public class VScrollTable extends FlowPanel } } else { c.setText(caption); + // IE10 is no longer supported } c.setSorted(false); diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTextArea.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTextArea.java index c5d229e153..b42f04f9b9 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTextArea.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTextArea.java @@ -230,6 +230,7 @@ public class VTextArea extends VTextField implements DragImageModifier { if (info.isSafari()) { return true; } + // Vaadin 8 no longer supports IE10 if (info.isIE11() || info.isEdge()) { return true; } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTwinColSelect.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTwinColSelect.java index 32bc14d330..2403750b03 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTwinColSelect.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VTwinColSelect.java @@ -367,6 +367,7 @@ public class VTwinColSelect extends VOptionGroupBase implements KeyDownHandler, /** For internal use only. May be removed or replaced in the future. */ public void clearInternalWidths() { + // Intentional removal of cols in compatibility package int cols = DEFAULT_COLUMN_COUNT; if (cols >= 0) { diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VUpload.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VUpload.java index 16108792b4..8f892e377e 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VUpload.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VUpload.java @@ -161,6 +161,7 @@ public class VUpload extends SimplePanel { private static native void setEncoding(Element form, String encoding) /*-{ form.enctype = encoding; + // IE8 not supported in Vaadin 8 }-*/; /** For internal use only. May be removed or replaced in the future. */ diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/form/FormConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/form/FormConnector.java index dcc83008b9..e904cd6803 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/form/FormConnector.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/form/FormConnector.java @@ -180,6 +180,7 @@ public class FormConnector extends AbstractComponentContainerConnector @Override public boolean isReadOnly() { + // Class hierarchy has changed for FormConnector return getState().readOnly || getState().propertyReadOnly; } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/optiongroup/OptionGroupBaseConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/optiongroup/OptionGroupBaseConnector.java index 53c0c0d06a..6fe94fa5a5 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/optiongroup/OptionGroupBaseConnector.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/optiongroup/OptionGroupBaseConnector.java @@ -43,6 +43,7 @@ public abstract class OptionGroupBaseConnector extends AbstractFieldConnector getWidget().selectedKeys = uidl.getStringArrayVariableAsSet("selected"); getWidget().setReadonly(isReadOnly()); + // Intentional change to use state over UIDL in compatibility package getWidget().multiselect = getState().multiSelect; getWidget().immediate = getState().immediate; getWidget().nullSelectionAllowed = uidl @@ -50,12 +51,16 @@ public abstract class OptionGroupBaseConnector extends AbstractFieldConnector getWidget().nullSelectionItemAvailable = uidl .getBooleanAttribute("nullselectitem"); + // Support for cols has been dropped. + if (uidl.hasAttribute("rows")) { getWidget().rows = uidl.getIntAttribute("rows"); } final UIDL ops = uidl.getChildUIDL(0); + // Method getColumns has been removed + getWidget().buildOptions(ops); if (uidl.getBooleanAttribute("allownewitem")) { diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/optiongroup/OptionGroupConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/optiongroup/OptionGroupConnector.java index e88a2070bc..dbed217598 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/optiongroup/OptionGroupConnector.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/optiongroup/OptionGroupConnector.java @@ -34,6 +34,7 @@ public class OptionGroupConnector extends OptionGroupBaseConnector { @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { + // HTML Content has been moved to state. super.updateFromUIDL(uidl, client); getWidget().sendFocusEvents = client.hasEventListeners(this, diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/table/TableConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/table/TableConnector.java index 9d2677af54..091951bc8b 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/table/TableConnector.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/table/TableConnector.java @@ -386,6 +386,8 @@ public class TableConnector extends AbstractFieldConnector public void updateEnabledState(boolean enabledState) { super.updateEnabledState(enabledState); getWidget().enabled = isEnabled(); + + // IE8 is no longer supported } @Override @@ -416,6 +418,7 @@ public class TableConnector extends AbstractFieldConnector Scheduler.get().scheduleFinally(new ScheduledCommand() { @Override public void execute() { + // IE8 is no longer supported getLayoutManager().setNeedsMeasure(TableConnector.this); ServerConnector parent = getParent(); if (parent instanceof ComponentConnector) { diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/tree/TreeConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/tree/TreeConnector.java index a589e75697..d03c0bf55a 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/tree/TreeConnector.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/tree/TreeConnector.java @@ -66,6 +66,8 @@ public class TreeConnector extends AbstractLegacyComponentConnector if (uidl.hasAttribute("partialUpdate")) { handleUpdate(uidl); + // IE8 is no longer supported with Vaadin 8 + getWidget().rendering = false; return; } @@ -175,6 +177,8 @@ public class TreeConnector extends AbstractLegacyComponentConnector getWidget().focusedNode.setFocused(false); } + // IE8 is no longer supported with Vaadin 8 + getWidget().rendering = false; } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/escalator/ScrollbarBundle.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/escalator/ScrollbarBundle.java index 20b1e5d1b9..8e6d9a5243 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/escalator/ScrollbarBundle.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/escalator/ScrollbarBundle.java @@ -362,6 +362,7 @@ public abstract class ScrollbarBundle implements DeferredWorker { private HandlerRegistration scrollSizeTemporaryScrollHandler; private HandlerRegistration offsetSizeTemporaryScrollHandler; + private HandlerRegistration scrollInProgress; private ScrollbarBundle() { root.appendChild(scrollSizeElement); @@ -435,6 +436,9 @@ public abstract class ScrollbarBundle implements DeferredWorker { boolean offsetSizeBecomesGreaterThanScrollSize = showsScrollHandle() && newOffsetSizeIsGreaterThanScrollSize; if (offsetSizeBecomesGreaterThanScrollSize && getScrollPos() != 0) { + if (offsetSizeTemporaryScrollHandler != null) { + offsetSizeTemporaryScrollHandler.removeHandler(); + } // must be a field because Java insists. offsetSizeTemporaryScrollHandler = addScrollHandler( new ScrollHandler() { @@ -523,6 +527,17 @@ public abstract class ScrollbarBundle implements DeferredWorker { scrollPos = Math.max(0, Math.min(maxScrollPos, truncate(px))); if (!WidgetUtil.pixelValuesEqual(oldScrollPos, scrollPos)) { + if (scrollInProgress == null) { + // Only used for tracking that there is "workPending" + scrollInProgress = addScrollHandler(new ScrollHandler() { + @Override + public void onScroll(ScrollEvent event) { + scrollInProgress.removeHandler(); + scrollInProgress = null; + } + }); + } + if (isInvisibleScrollbar) { invisibleScrollbarTemporaryResizer.show(); } @@ -631,7 +646,7 @@ public abstract class ScrollbarBundle implements DeferredWorker { * This needs to be made step-by-step because IE8 flat-out refuses to * fire a scroll event when the scroll size becomes smaller than the * offset size. All other browser need to suffer alongside. - * + * * This really should be changed to not use any temporary scroll * handlers at all once IE8 support is dropped, like now done only for * Firefox. @@ -649,7 +664,11 @@ public abstract class ScrollbarBundle implements DeferredWorker { * 'delayedSizeSet' */ boolean delayedSizeSet = !BrowserInfo.get().isFirefox(); + // must be a field because Java insists. if (delayedSizeSet) { + if (scrollSizeTemporaryScrollHandler != null) { + scrollSizeTemporaryScrollHandler.removeHandler(); + } scrollSizeTemporaryScrollHandler = addScrollHandler( new ScrollHandler() { @Override @@ -911,6 +930,6 @@ public abstract class ScrollbarBundle implements DeferredWorker { // requestAnimationFrame - which is not automatically checked return scrollSizeTemporaryScrollHandler != null || offsetSizeTemporaryScrollHandler != null - || scrollEventFirer.isBeingFired; + || scrollInProgress != null || scrollEventFirer.isBeingFired; } } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/EditorHandler.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/EditorHandler.java index a0fee4c7fc..7777b821bc 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/EditorHandler.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/EditorHandler.java @@ -54,9 +54,9 @@ public interface EditorHandler<T> { public int getRowIndex(); /** - * Returns the index of the column being focused. + * Returns the DOM index of the column being focused. * - * @return the column index + * @return the column index (excluding hidden columns) */ public int getColumnIndex(); diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/GridEventHandler.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/GridEventHandler.java index 0e3e65179e..1e792f9796 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/GridEventHandler.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/GridEventHandler.java @@ -27,8 +27,8 @@ public interface GridEventHandler<T> { /** * Attempts to handle the given grid event. * - * @param gridEvent + * @param event * the event that occurred */ - public void onEvent(GridEvent<T> gridEvent); -}
\ No newline at end of file + public void onEvent(GridEvent<T> event); +} diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/ClickSelectHandler.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/ClickSelectHandler.java index 588d8a354b..6887f571b5 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/ClickSelectHandler.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/ClickSelectHandler.java @@ -36,6 +36,10 @@ public class ClickSelectHandler<T> { @Override public void onClick(GridClickEvent event) { + if (!grid.isUserSelectionAllowed()) { + return; + } + T row = (T) event.getTargetCell().getRow(); if (!grid.isSelected(row)) { grid.select(row); diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/HasUserSelectionAllowed.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/HasUserSelectionAllowed.java new file mode 100644 index 0000000000..82aa86fae6 --- /dev/null +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/HasUserSelectionAllowed.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.v7.client.widget.grid.selection; + +/** + * Interface implemented by selection models which support disabling client side + * selection while still allowing programmatic selection on the server. + * + * @param <T> + * Grid's row type + * + * @since 7.7.7 + */ +public interface HasUserSelectionAllowed<T> extends SelectionModel<T> { + + /** + * Checks if the user is allowed to change the selection. + * + * @return <code>true</code> if the user is allowed to change the selection, + * <code>false</code> otherwise + */ + public boolean isUserSelectionAllowed(); + + /** + * Sets whether the user is allowed to change the selection. + * + * @param userSelectionAllowed + * <code>true</code> if the user is allowed to change the + * selection, <code>false</code> otherwise + */ + public void setUserSelectionAllowed(boolean userSelectionAllowed); + +} diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/MultiSelectionRenderer.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/MultiSelectionRenderer.java index a7c974aead..86d5e0a323 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/MultiSelectionRenderer.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/MultiSelectionRenderer.java @@ -632,7 +632,8 @@ public class MultiSelectionRenderer<T> public void render(final RendererCellReference cell, final Boolean data, CheckBox checkBox) { checkBox.setValue(data, false); - checkBox.setEnabled(grid.isEnabled() && !grid.isEditorActive()); + checkBox.setEnabled(grid.isEnabled() && !grid.isEditorActive() + && grid.isUserSelectionAllowed()); } @Override @@ -770,6 +771,10 @@ public class MultiSelectionRenderer<T> } protected void setSelected(final int logicalRow, final boolean select) { + if (!grid.isUserSelectionAllowed()) { + return; + } + T row = grid.getDataSource().getRow(logicalRow); if (select) { grid.select(row); diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/SelectionModelMulti.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/SelectionModelMulti.java index 8629a5af3a..a93360d77a 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/SelectionModelMulti.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/SelectionModelMulti.java @@ -33,7 +33,7 @@ import com.vaadin.v7.client.widgets.Grid; * @since 7.4 */ public class SelectionModelMulti<T> extends AbstractRowHandleSelectionModel<T> - implements SelectionModel.Multi.Batched<T> { + implements SelectionModel.Multi.Batched<T>, HasUserSelectionAllowed<T> { private final LinkedHashSet<RowHandle<T>> selectedRows; private Renderer<Boolean> renderer; @@ -45,6 +45,7 @@ public class SelectionModelMulti<T> extends AbstractRowHandleSelectionModel<T> /* Event handling for selection with space key */ private SpaceSelectHandler<T> spaceSelectHandler; + private boolean userSelectionAllowed = true; public SelectionModelMulti() { grid = null; @@ -270,4 +271,14 @@ public class SelectionModelMulti<T> extends AbstractRowHandleSelectionModel<T> } return rows; } + + @Override + public boolean isUserSelectionAllowed() { + return userSelectionAllowed; + } + + @Override + public void setUserSelectionAllowed(boolean userSelectionAllowed) { + this.userSelectionAllowed = userSelectionAllowed; + } } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/SelectionModelSingle.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/SelectionModelSingle.java index 6467759d6e..d78fbc2ba1 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/SelectionModelSingle.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/SelectionModelSingle.java @@ -29,7 +29,7 @@ import com.vaadin.v7.client.widgets.Grid; * @since 7.4 */ public class SelectionModelSingle<T> extends AbstractRowHandleSelectionModel<T> - implements SelectionModel.Single<T> { + implements SelectionModel.Single<T>, HasUserSelectionAllowed<T> { private Grid<T> grid; private RowHandle<T> selectedRow; @@ -41,6 +41,7 @@ public class SelectionModelSingle<T> extends AbstractRowHandleSelectionModel<T> private ClickSelectHandler<T> clickSelectHandler; private boolean deselectAllowed = true; + private boolean userSelectionAllowed = true; @Override public boolean isSelected(T row) { @@ -172,4 +173,13 @@ public class SelectionModelSingle<T> extends AbstractRowHandleSelectionModel<T> } } + @Override + public boolean isUserSelectionAllowed() { + return userSelectionAllowed; + } + + @Override + public void setUserSelectionAllowed(boolean userSelectionAllowed) { + this.userSelectionAllowed = userSelectionAllowed; + } } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/SpaceSelectHandler.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/SpaceSelectHandler.java index d4c0f2219f..8de75dde2b 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/SpaceSelectHandler.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/selection/SpaceSelectHandler.java @@ -44,6 +44,10 @@ public class SpaceSelectHandler<T> { @Override public void onKeyDown(GridKeyDownEvent event) { + if (!grid.isUserSelectionAllowed()) { + return; + } + if (event.getNativeKeyCode() != KeyCodes.KEY_SPACE || spaceDown) { return; } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Escalator.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Escalator.java index cb2786a4cf..e9879b9b23 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Escalator.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Escalator.java @@ -308,6 +308,8 @@ public class Escalator extends Widget static class JsniUtil { public static class TouchHandlerBundle { + public static final String POINTER_EVENT_TYPE_TOUCH = "touch"; + /** * A <a href= * "http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsOverlay.html" @@ -340,6 +342,11 @@ public class Escalator extends Widget /*-{ return this.targetTouches[0].pageY; }-*/; + + public native String getPointerType() + /*-{ + return this.pointerType; + }-*/; } private final Escalator escalator; @@ -457,6 +464,15 @@ public class Escalator extends Widget } int pagePosition(CustomTouchEvent event) { + // Use native event's screen x and y for IE11 and Edge + // since there is no touches for these browsers (#18737) + if (isCurrentBrowserIE11OrEdge()) { + return vertical + ? event.getNativeEvent().getClientY() + + Window.getScrollTop() + : event.getNativeEvent().getClientX() + + Window.getScrollLeft(); + } JsArray<Touch> a = event.getNativeEvent().getTouches(); return vertical ? a.get(0).getPageY() : a.get(0).getPageX(); } @@ -496,7 +512,7 @@ public class Escalator extends Widget }; public void touchStart(final CustomTouchEvent event) { - if (event.getNativeEvent().getTouches().length() == 1) { + if (allowTouch(event)) { if (yMov == null) { yMov = new Movement(true); xMov = new Movement(false); @@ -544,6 +560,20 @@ public class Escalator extends Widget } } + // Allow touchStart for IE11 and Edge even though there is no touch + // (#18737), + // otherwise allow touch only if there is a single touch in the + // event + private boolean allowTouch( + final TouchHandlerBundle.CustomTouchEvent event) { + if (isCurrentBrowserIE11OrEdge()) { + return (POINTER_EVENT_TYPE_TOUCH + .equals(event.getPointerType())); + } else { + return (event.getNativeEvent().getTouches().length() == 1); + } + } + private double easingInOutCos(double val, double max) { return 0.5 - 0.5 * Math.cos(Math.PI * Math.signum(val) * Math.min(Math.abs(val), max) / max); @@ -859,8 +889,8 @@ public class Escalator extends Widget if (position instanceof AbsolutePosition) { /* * we don't want to put "top: 0" on the footer, since it'll - * render wrong, as we already have "bottom: $footer-height" - * . + * render wrong, as we already have + * "bottom: $footer-height". */ footElem.getStyle().setLeft(-scrollLeft, Unit.PX); } else { @@ -901,7 +931,7 @@ public class Escalator extends Widget public native void detachScrollListener(Element element) /* - * Attaching events with JSNI instead of the GWT event mechanism because + * Detaching events with JSNI instead of the GWT event mechanism because * GWT didn't provide enough details in events, or triggering the event * handlers with GWT bindings was unsuccessful. Maybe, with more time * and skill, it could be done with better success. JavaScript overlay @@ -978,6 +1008,50 @@ public class Escalator extends Widget element.removeEventListener("touchcancel", this.@com.vaadin.v7.client.widgets.JsniWorkaround::touchEndFunction); }-*/; + /** + * Using pointerdown, pointermove, pointerup, and pointercancel for IE11 + * and Edge instead of touch* listeners (#18737) + * + * @param element + */ + public native void attachPointerEventListeners(Element element) + /* + * Attaching events with JSNI instead of the GWT event mechanism because + * GWT didn't provide enough details in events, or triggering the event + * handlers with GWT bindings was unsuccessful. Maybe, with more time + * and skill, it could be done with better success. JavaScript overlay + * types might work. This might also get rid of the JsniWorkaround + * class. + */ + /*-{ + element.addEventListener("pointerdown", this.@com.vaadin.client.widgets.JsniWorkaround::touchStartFunction); + element.addEventListener("pointermove", this.@com.vaadin.client.widgets.JsniWorkaround::touchMoveFunction); + element.addEventListener("pointerup", this.@com.vaadin.client.widgets.JsniWorkaround::touchEndFunction); + element.addEventListener("pointercancel", this.@com.vaadin.client.widgets.JsniWorkaround::touchEndFunction); + }-*/; + + /** + * Using pointerdown, pointermove, pointerup, and pointercancel for IE11 + * and Edge instead of touch* listeners (#18737) + * + * @param element + */ + public native void detachPointerEventListeners(Element element) + /* + * Detaching events with JSNI instead of the GWT event mechanism because + * GWT didn't provide enough details in events, or triggering the event + * handlers with GWT bindings was unsuccessful. Maybe, with more time + * and skill, it could be done with better success. JavaScript overlay + * types might work. This might also get rid of the JsniWorkaround + * class. + */ + /*-{ + element.removeEventListener("pointerdown", this.@com.vaadin.client.widgets.JsniWorkaround::touchStartFunction); + element.removeEventListener("pointermove", this.@com.vaadin.client.widgets.JsniWorkaround::touchMoveFunction); + element.removeEventListener("pointerup", this.@com.vaadin.client.widgets.JsniWorkaround::touchEndFunction); + element.removeEventListener("pointercancel", this.@com.vaadin.client.widgets.JsniWorkaround::touchEndFunction); + }-*/; + public void scrollToColumn(final int columnIndex, final ScrollDestination destination, final int padding) { assert columnIndex >= columnConfiguration.frozenColumns : "Can't scroll to a frozen column"; @@ -4197,6 +4271,11 @@ public class Escalator extends Widget frozenColumns += numberOfColumns; } + // Add to DOM + header.paintInsertColumns(index, numberOfColumns, frozen); + body.paintInsertColumns(index, numberOfColumns, frozen); + footer.paintInsertColumns(index, numberOfColumns, frozen); + // this needs to be before the scrollbar adjustment. boolean scrollbarWasNeeded = horizontalScrollbar .getOffsetSize() < horizontalScrollbar.getScrollSize(); @@ -4204,14 +4283,12 @@ public class Escalator extends Widget boolean scrollbarIsNowNeeded = horizontalScrollbar .getOffsetSize() < horizontalScrollbar.getScrollSize(); if (!scrollbarWasNeeded && scrollbarIsNowNeeded) { + // This might as a side effect move rows around (when scrolled + // all the way down) and require the DOM to be up to date, i.e. + // the column to be added body.verifyEscalatorCount(); } - // Add to DOM - header.paintInsertColumns(index, numberOfColumns, frozen); - body.paintInsertColumns(index, numberOfColumns, frozen); - footer.paintInsertColumns(index, numberOfColumns, frozen); - // fix initial width if (header.getRowCount() > 0 || body.getRowCount() > 0 || footer.getRowCount() > 0) { @@ -5741,7 +5818,13 @@ public class Escalator extends Widget scroller.attachScrollListener(verticalScrollbar.getElement()); scroller.attachScrollListener(horizontalScrollbar.getElement()); scroller.attachMousewheelListener(getElement()); - scroller.attachTouchListeners(getElement()); + + if (isCurrentBrowserIE11OrEdge()) { + // Touch listeners doesn't work for IE11 and Edge (#18737) + scroller.attachPointerEventListeners(getElement()); + } else { + scroller.attachTouchListeners(getElement()); + } } @Override @@ -5750,7 +5833,13 @@ public class Escalator extends Widget scroller.detachScrollListener(verticalScrollbar.getElement()); scroller.detachScrollListener(horizontalScrollbar.getElement()); scroller.detachMousewheelListener(getElement()); - scroller.detachTouchListeners(getElement()); + + if (isCurrentBrowserIE11OrEdge()) { + // Touch listeners doesn't work for IE11 and Edge (#18737) + scroller.detachPointerEventListeners(getElement()); + } else { + scroller.detachTouchListeners(getElement()); + } /* * We can call paintRemoveRows here, because static ranges are simple to @@ -6807,4 +6896,13 @@ public class Escalator extends Widget double getMinCellWidth(int colIndex) { return columnConfiguration.getMinCellWidth(colIndex); } + + /** + * Internal method for checking whether the browser is IE11 or Edge + * + * @return true only if the current browser is IE11, or Edge + */ + private static boolean isCurrentBrowserIE11OrEdge() { + return BrowserInfo.get().isIE11() || BrowserInfo.get().isEdge(); + } } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java index 5e48188128..ea7901773d 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java @@ -81,6 +81,7 @@ import com.vaadin.client.BrowserInfo; import com.vaadin.client.DeferredWorker; import com.vaadin.client.Focusable; import com.vaadin.client.WidgetUtil; +import com.vaadin.client.data.AbstractRemoteDataSource; import com.vaadin.client.data.DataChangeHandler; import com.vaadin.client.data.DataSource; import com.vaadin.client.data.DataSource.RowHandle; @@ -96,7 +97,9 @@ import com.vaadin.shared.Registration; import com.vaadin.shared.data.sort.SortDirection; import com.vaadin.shared.util.SharedUtil; import com.vaadin.v7.client.renderers.ComplexRenderer; +import com.vaadin.v7.client.renderers.ProgressBarRenderer; import com.vaadin.v7.client.renderers.Renderer; +import com.vaadin.v7.client.renderers.TextRenderer; import com.vaadin.v7.client.renderers.WidgetRenderer; import com.vaadin.v7.client.widget.escalator.Cell; import com.vaadin.v7.client.widget.escalator.ColumnConfiguration; @@ -128,6 +131,7 @@ import com.vaadin.v7.client.widget.grid.HeightAwareDetailsGenerator; import com.vaadin.v7.client.widget.grid.RendererCellReference; import com.vaadin.v7.client.widget.grid.RowReference; import com.vaadin.v7.client.widget.grid.RowStyleGenerator; +import com.vaadin.v7.client.widget.grid.datasources.ListDataSource; import com.vaadin.v7.client.widget.grid.events.AbstractGridKeyEventHandler; import com.vaadin.v7.client.widget.grid.events.AbstractGridMouseEventHandler; import com.vaadin.v7.client.widget.grid.events.BodyClickHandler; @@ -163,6 +167,7 @@ import com.vaadin.v7.client.widget.grid.events.ScrollHandler; import com.vaadin.v7.client.widget.grid.events.SelectAllEvent; import com.vaadin.v7.client.widget.grid.events.SelectAllHandler; import com.vaadin.v7.client.widget.grid.selection.HasSelectionHandlers; +import com.vaadin.v7.client.widget.grid.selection.HasUserSelectionAllowed; import com.vaadin.v7.client.widget.grid.selection.MultiSelectionRenderer; import com.vaadin.v7.client.widget.grid.selection.SelectionEvent; import com.vaadin.v7.client.widget.grid.selection.SelectionHandler; @@ -201,12 +206,10 @@ import com.vaadin.v7.shared.ui.grid.ScrollDestination; * <p> * Each column also has a Renderer. Its function is to take the value that is * given by the {@code GridColumn} and display it to the user. A simple column - * might have a {@link com.vaadin.v7.client.renderers.TextRenderer TextRenderer} - * that simply takes in a {@code String} and displays it as the cell's content. - * A more complex renderer might be - * {@link com.vaadin.v7.client.renderers.ProgressBarRenderer - * ProgressBarRenderer} that takes in a floating point number, and displays a - * progress bar instead, based on the given number. + * might have a {@link TextRenderer} that simply takes in a {@code String} and + * displays it as the cell's content. A more complex renderer might be + * {@link ProgressBarRenderer} that takes in a floating point number, and + * displays a progress bar instead, based on the given number. * <p> * <em>See:</em> {@link #addColumn(Column)}, {@link #addColumn(Column, int)} and * {@link #addColumns(Column...)}. <em>Also</em> @@ -216,10 +219,8 @@ import com.vaadin.v7.shared.ui.grid.ScrollDestination; * <p> * Grid gets its data from a {@link DataSource}, providing row objects to Grid * from a user-defined endpoint. It can be either a local in-memory data source - * (e.g. {@link com.vaadin.v7.client.widget.grid.datasources.ListDataSource - * ListDataSource}) or even a remote one, retrieving data from e.g. a REST API - * (see {@link com.vaadin.client.data.AbstractRemoteDataSource - * AbstractRemoteDataSource}). + * (e.g. {@link ListDataSource}) or even a remote one, retrieving data from e.g. + * a REST API (see {@link AbstractRemoteDataSource}). * * * @param <T> @@ -445,14 +446,14 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public abstract static class StaticRow<CELLTYPE extends StaticCell> { - private Map<Column<?, ?>, CELLTYPE> cells = new HashMap<>(); + private Map<Column<?, ?>, CELLTYPE> cells = new HashMap<Column<?, ?>, CELLTYPE>(); private StaticSection<?> section; /** * Map from set of spanned columns to cell meta data. */ - private Map<Set<Column<?, ?>>, CELLTYPE> cellGroups = new HashMap<>(); + private Map<Set<Column<?, ?>>, CELLTYPE> cellGroups = new HashMap<Set<Column<?, ?>>, CELLTYPE>(); /** * A custom style name for the row or null if none is set. @@ -500,7 +501,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, "You can't merge less than 2 columns together."); } - HashSet<Column<?, ?>> columnGroup = new HashSet<>(); + HashSet<Column<?, ?>> columnGroup = new HashSet<Column<?, ?>>(); // NOTE: this doesn't care about hidden columns, those are // filtered in calculateColspans() for (Column<?, ?> column : columns) { @@ -594,7 +595,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private boolean checkMergedCellIsContinuous( Set<Column<?, ?>> mergedCell) { // no matter if hidden or not, just check for continuous order - final List<Column<?, ?>> columnOrder = new ArrayList<>( + final List<Column<?, ?>> columnOrder = new ArrayList<Column<?, ?>>( section.grid.getColumns()); if (!columnOrder.containsAll(mergedCell)) { @@ -664,7 +665,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ void detach() { // Avoid calling detach twice for a merged cell - HashSet<CELLTYPE> cells = new HashSet<>(); + HashSet<CELLTYPE> cells = new HashSet<CELLTYPE>(); for (Column<?, ?> column : getSection().grid.getColumns()) { cells.add(getCell(column)); } @@ -676,7 +677,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private Grid<?> grid; - private List<ROWTYPE> rows = new ArrayList<>(); + private List<ROWTYPE> rows = new ArrayList<ROWTYPE>(); private boolean visible = true; @@ -1100,15 +1101,15 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private Grid<T> grid; private final int rowIndex; - private final int columnIndex; + private final int columnIndexDOM; private RequestCallback<T> callback; private boolean completed = false; - public EditorRequestImpl(Grid<T> grid, int rowIndex, int columnIndex, + public EditorRequestImpl(Grid<T> grid, int rowIndex, int columnIndexDOM, RequestCallback<T> callback) { this.grid = grid; this.rowIndex = rowIndex; - this.columnIndex = columnIndex; + this.columnIndexDOM = columnIndexDOM; this.callback = callback; } @@ -1119,7 +1120,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, @Override public int getColumnIndex() { - return columnIndex; + return columnIndexDOM; } @Override @@ -1289,13 +1290,13 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } /** - * Returns the column index the editor was opened at. If the editor is - * not open, returns -1. + * Returns the DOM column index (excluding hidden columns) the editor + * was opened at. If the editor is not open, returns -1. * * @return the column index or -1 if editor is not open */ public int getFocusedColumnIndex() { - return getEditor().focusedColumnIndex; + return getEditor().focusedColumnIndexDOM; } } @@ -1315,6 +1316,23 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private static final String ERROR_CLASS_NAME = "error"; private static final String NOT_EDITABLE_CLASS_NAME = "not-editable"; + ScheduledCommand fieldFocusCommand = new ScheduledCommand() { + private int count = 0; + + @Override + public void execute() { + Element focusedElement = WidgetUtil.getFocusedElement(); + if (focusedElement == grid.getElement() + || focusedElement == Document.get().getBody() + || count > 2) { + focusColumn(focusedColumnIndexDOM); + } else { + ++count; + Scheduler.get().scheduleDeferred(this); + } + } + }; + /** * A handler for events related to the Grid editor. Responsible for * opening, moving or closing the editor based on the received event. @@ -1360,13 +1378,13 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, // Should only be added to the DOM when there's a message to show private DivElement message = DivElement.as(DOM.createDiv()); - private Map<Column<?, T>, Widget> columnToWidget = new HashMap<>(); - private List<HandlerRegistration> focusHandlers = new ArrayList<>(); + private Map<Column<?, T>, Widget> columnToWidget = new HashMap<Column<?, T>, Widget>(); + private List<HandlerRegistration> focusHandlers = new ArrayList<HandlerRegistration>(); private boolean enabled = false; private State state = State.INACTIVE; private int rowIndex = -1; - private int focusedColumnIndex = -1; + private int focusedColumnIndexDOM = -1; private String styleName = null; private HandlerRegistration hScrollHandler; @@ -1431,10 +1449,10 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, bindTimeout.cancel(); rowIndex = request.getRowIndex(); - focusedColumnIndex = request.getColumnIndex(); - if (focusedColumnIndex >= 0) { + focusedColumnIndexDOM = request.getColumnIndex(); + if (focusedColumnIndexDOM >= 0) { // Update internal focus of Grid - grid.focusCell(rowIndex, focusedColumnIndex); + grid.focusCell(rowIndex, focusedColumnIndexDOM); } showOverlay(); @@ -1456,7 +1474,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, }; /** A set of all the columns that display an error flag. */ - private final Set<Column<?, T>> columnErrors = new HashSet<>(); + private final Set<Column<?, T>> columnErrors = new HashSet<Column<?, T>>(); private boolean buffered = true; /** Original position of editor */ @@ -1543,9 +1561,10 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * * @param rowIndex * the index of the row to be edited - * @param columnIndex - * the column index of the editor widget that should be - * initially focused or -1 to not set focus + * @param columnIndexDOM + * the column index (excluding hidden columns) of the editor + * widget that should be initially focused or -1 to not set + * focus * * @throws IllegalStateException * if this editor is not enabled @@ -1555,7 +1574,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * * @since 7.5 */ - public void editRow(final int rowIndex, final int columnIndex) { + public void editRow(final int rowIndex, final int columnIndexDOM) { if (!enabled) { throw new IllegalStateException( "Cannot edit row: editor is not enabled"); @@ -1580,35 +1599,35 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, return; } } - if (columnIndex >= grid.getVisibleColumns().size()) { + if (columnIndexDOM >= grid.getVisibleColumns().size()) { throw new IllegalArgumentException( - "Edited column index " + columnIndex + "Edited column index " + columnIndexDOM + " was bigger than visible column count."); } if (this.rowIndex == rowIndex - && focusedColumnIndex == columnIndex) { + && focusedColumnIndexDOM == columnIndexDOM) { // NO-OP return; } if (this.rowIndex == rowIndex) { - if (focusedColumnIndex != columnIndex) { - if (columnIndex >= grid.getFrozenColumnCount()) { + if (focusedColumnIndexDOM != columnIndexDOM) { + if (columnIndexDOM >= grid.getFrozenColumnCount()) { // Scroll to new focused column. - grid.getEscalator().scrollToColumn(columnIndex, + grid.getEscalator().scrollToColumn(columnIndexDOM, ScrollDestination.ANY, 0); } - focusedColumnIndex = columnIndex; + focusedColumnIndexDOM = columnIndexDOM; } updateHorizontalScrollPosition(); // Update Grid internal focus and focus widget if possible - if (focusedColumnIndex >= 0) { - grid.focusCell(rowIndex, focusedColumnIndex); - focusColumn(focusedColumnIndex); + if (focusedColumnIndexDOM >= 0) { + grid.focusCell(rowIndex, focusedColumnIndexDOM); + focusColumn(focusedColumnIndexDOM); } // No need to request anything from the editor handler. @@ -1618,13 +1637,13 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, final Escalator escalator = grid.getEscalator(); if (escalator.getVisibleRowRange().contains(rowIndex)) { - show(rowIndex, columnIndex); + show(rowIndex, columnIndexDOM); } else { vScrollHandler = grid.addScrollHandler(new ScrollHandler() { @Override public void onScroll(ScrollEvent event) { if (escalator.getVisibleRowRange().contains(rowIndex)) { - show(rowIndex, columnIndex); + show(rowIndex, columnIndexDOM); vScrollHandler.removeHandler(); } } @@ -1652,8 +1671,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, throw new IllegalStateException( "Cannot cancel edit: editor is not in edit mode"); } - handler.cancel(new EditorRequestImpl<>(grid, rowIndex, - focusedColumnIndex, null)); + handler.cancel(new EditorRequestImpl<T>(grid, rowIndex, + focusedColumnIndexDOM, null)); doCancel(); } @@ -1661,7 +1680,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, hideOverlay(); state = State.INACTIVE; rowIndex = -1; - focusedColumnIndex = -1; + focusedColumnIndexDOM = -1; grid.getEscalator().setScrollLocked(Direction.VERTICAL, false); updateSelectionCheckboxesAsNeeded(true); } @@ -1698,8 +1717,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, state = State.SAVING; setButtonsEnabled(false); saveTimeout.schedule(SAVE_TIMEOUT_MS); - EditorRequest<T> request = new EditorRequestImpl<>(grid, rowIndex, - focusedColumnIndex, saveRequestCallback); + EditorRequest<T> request = new EditorRequestImpl<T>(grid, rowIndex, + focusedColumnIndexDOM, saveRequestCallback); handler.save(request); updateSelectionCheckboxesAsNeeded(true); } @@ -1762,7 +1781,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, if (state == State.ACTIVATING) { state = State.BINDING; bindTimeout.schedule(BIND_TIMEOUT_MS); - EditorRequest<T> request = new EditorRequestImpl<>(grid, + EditorRequest<T> request = new EditorRequestImpl<T>(grid, rowIndex, columnIndex, bindRequestCallback); handler.bind(request); grid.getEscalator().setScrollLocked(Direction.VERTICAL, @@ -1871,8 +1890,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, grid.attachWidget(editor, cell); } - if (i == focusedColumnIndex) { - focusColumn(focusedColumnIndex); + if (i == focusedColumnIndexDOM) { + focusColumn(focusedColumnIndexDOM); } } else { cell.addClassName(NOT_EDITABLE_CLASS_NAME); @@ -1902,6 +1921,9 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, checkBox.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { + if (!grid.isUserSelectionAllowed()) { + return; + } T row = pinnedRowHandle.getRow(); if (grid.isSelected(row)) { grid.deselect(row); @@ -1975,13 +1997,14 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, Unit.PX); } - private void focusColumn(int colIndex) { - if (colIndex < 0 || colIndex >= grid.getVisibleColumns().size()) { + private void focusColumn(int columnIndexDOM) { + if (columnIndexDOM < 0 + || columnIndexDOM >= grid.getVisibleColumns().size()) { // NO-OP return; } - Widget editor = getWidget(grid.getVisibleColumn(colIndex)); + Widget editor = getWidget(grid.getVisibleColumn(columnIndexDOM)); if (editor instanceof Focusable) { ((Focusable) editor).focus(); } else if (editor instanceof com.google.gwt.user.client.ui.Focusable) { @@ -2293,7 +2316,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, extends KeyEvent<HANDLER> { private Grid<?> grid; - private final Type<HANDLER> associatedType = new Type<>( + private final Type<HANDLER> associatedType = new Type<HANDLER>( getBrowserEventType(), this); private final CellReference<?> targetCell; @@ -2353,7 +2376,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private Grid<?> grid; private final CellReference<?> targetCell; - private final Type<HANDLER> associatedType = new Type<>( + private final Type<HANDLER> associatedType = new Type<HANDLER>( getBrowserEventType(), this); public AbstractGridMouseEvent(Grid<?> grid, @@ -2431,7 +2454,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ private static final double DETAILS_ROW_INITIAL_HEIGHT = 50; - private EventCellReference<T> eventCell = new EventCellReference<>(this); + private EventCellReference<T> eventCell = new EventCellReference<T>(this); private GridKeyDownEvent keyDown = new GridKeyDownEvent(this, eventCell); private GridKeyUpEvent keyUp = new GridKeyUpEvent(this, eventCell); private GridKeyPressEvent keyPress = new GridKeyPressEvent(this, eventCell); @@ -2514,8 +2537,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, setStyleName(rowWithFocusStyle, rowFocusStyleName, true); } } else if (rowWithFocusStyle == row.getElement() - || (containerWithFocus != escalator.getBody() - && rowWithFocusStyle != null)) { + || containerWithFocus != escalator.getBody() + && rowWithFocusStyle != null) { // Remove focus style. setStyleName(rowWithFocusStyle, rowFocusStyleName, false); rowWithFocusStyle = null; @@ -2566,9 +2589,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, ++i; } while (cell != null); } - int columnIndex = getColumns() - .indexOf(getVisibleColumn(columnIndexDOM)); - if (columnIndex >= escalator.getColumnConfiguration() + if (columnIndexDOM >= escalator.getColumnConfiguration() .getFrozenColumnCount()) { escalator.scrollToColumn(columnIndexDOM, ScrollDestination.ANY, 10); @@ -2812,9 +2833,9 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * a range of added rows */ public void rowsAddedToBody(Range added) { - boolean bodyHasFocus = (containerWithFocus == escalator.getBody()); - boolean insertionIsAboveFocusedCell = (added - .getStart() <= rowWithFocus); + boolean bodyHasFocus = containerWithFocus == escalator.getBody(); + boolean insertionIsAboveFocusedCell = added + .getStart() <= rowWithFocus; if (bodyHasFocus && insertionIsAboveFocusedCell) { rowWithFocus += added.length(); rowWithFocus = Math.min(rowWithFocus, @@ -2860,12 +2881,12 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } } - private final List<GridEventHandler<T>> browserEventHandlers = new ArrayList<>(); + private final List<GridEventHandler<T>> browserEventHandlers = new ArrayList<GridEventHandler<T>>(); private CellStyleGenerator<T> cellStyleGenerator; private RowStyleGenerator<T> rowStyleGenerator; - private RowReference<T> rowReference = new RowReference<>(this); - private CellReference<T> cellReference = new CellReference<>(rowReference); + private RowReference<T> rowReference = new RowReference<T>(this); + private CellReference<T> cellReference = new CellReference<T>(rowReference); private RendererCellReference rendererCellReference = new RendererCellReference( (RowReference<Object>) rowReference); @@ -2875,6 +2896,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private boolean initDone = false; private boolean selected = false; private CheckBox selectAllCheckBox; + private boolean userSelectionAllowed = true; + private boolean enabled = true; SelectionColumn(final Renderer<Boolean> selectColumnRenderer) { super(selectColumnRenderer); @@ -2905,6 +2928,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, if (selectAllCheckBox == null) { selectAllCheckBox = GWT.create(CheckBox.class); + selectAllCheckBox.setEnabled(enabled && userSelectionAllowed); selectAllCheckBox.setStylePrimaryName( getStylePrimaryName() + SELECT_ALL_CHECKBOX_CLASSNAME); selectAllCheckBox.addValueChangeHandler( @@ -2913,8 +2937,11 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, @Override public void onValueChange( ValueChangeEvent<Boolean> event) { + if (!isUserSelectionAllowed()) { + return; + } if (event.getValue()) { - fireEvent(new SelectAllEvent<>(model)); + fireEvent(new SelectAllEvent<T>(model)); selected = true; } else { model.deselectAll(); @@ -2927,6 +2954,10 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, addHeaderClickHandler(new HeaderClickHandler() { @Override public void onClick(GridClickEvent event) { + if (!userSelectionAllowed) { + return; + } + CellReference<?> targetCell = event.getTargetCell(); int defaultRowIndex = getHeader().getRows() .indexOf(getDefaultHeaderRow()); @@ -2946,6 +2977,10 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, if (event.getNativeKeyCode() != KeyCodes.KEY_SPACE) { return; } + if (!isUserSelectionAllowed()) { + return; + } + HeaderRow targetHeaderRow = getHeader() .getRow(event.getFocusedCell().getRowIndex()); if (!targetHeaderRow.isDefault()) { @@ -3041,8 +3076,9 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * to disable it. */ public void setEnabled(boolean enabled) { + this.enabled = enabled; if (selectAllCheckBox != null) { - selectAllCheckBox.setEnabled(enabled); + selectAllCheckBox.setEnabled(enabled && userSelectionAllowed); } } @@ -3050,6 +3086,27 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, public void onEnabled(boolean enabled) { setEnabled(enabled); } + + /** + * Sets whether the user is allowed to change the selection. + * + * @param userSelectionAllowed + * <code>true</code> if the user is allowed to change the + * selection, <code>false</code> otherwise + * @since 7.7.7 + */ + public void setUserSelectionAllowed(boolean userSelectionAllowed) { + if (userSelectionAllowed == this.userSelectionAllowed) { + return; + } + + this.userSelectionAllowed = userSelectionAllowed; + // Update checkbox state + setEnabled(enabled); + // Re-render select checkboxes + getEscalator().getBody().refreshRows(0, + getEscalator().getBody().getRowCount()); + } } /** @@ -3201,6 +3258,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } } else if (currentDataAvailable.isEmpty() && dataSource.isWaitingForData()) { + // No data available yet but something is incoming soon Scheduler.get().scheduleDeferred(this); } else { calculate(); @@ -3235,7 +3293,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private void calculate() { isScheduled = false; rescheduleCount = 0; - assert !(currentDataAvailable.isEmpty() && dataSource .isWaitingForData()) : "Trying to calculate column widths without data while data is still being fetched."; @@ -3266,7 +3323,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, /* Step 1: Apply all column widths as they are. */ - Map<Integer, Double> selfWidths = new LinkedHashMap<>(); + Map<Integer, Double> selfWidths = new LinkedHashMap<Integer, Double>(); List<Column<?, T>> columns = getVisibleColumns(); for (int index = 0; index < columns.size(); index++) { selfWidths.put(index, columns.get(index).getWidth()); @@ -3280,7 +3337,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * violated, fix it. */ - Map<Integer, Double> constrainedWidths = new LinkedHashMap<>(); + Map<Integer, Double> constrainedWidths = new LinkedHashMap<Integer, Double>(); for (int index = 0; index < columns.size(); index++) { Column<?, T> column = columns.get(index); @@ -3305,9 +3362,9 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, boolean defaultExpandRatios = true; int totalRatios = 0; double reservedPixels = 0; - final Set<Column<?, T>> columnsToExpand = new HashSet<>(); - List<Column<?, T>> nonFixedColumns = new ArrayList<>(); - Map<Integer, Double> columnSizes = new HashMap<>(); + final Set<Column<?, T>> columnsToExpand = new HashSet<Column<?, T>>(); + List<Column<?, T>> nonFixedColumns = new ArrayList<Column<?, T>>(); + Map<Integer, Double> columnSizes = new HashMap<Integer, Double>(); final List<Column<?, T>> visibleColumns = getVisibleColumns(); /* @@ -3340,8 +3397,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, setColumnSizes(columnSizes); for (Column<?, T> column : nonFixedColumns) { - final int expandRatio = (defaultExpandRatios ? 1 - : column.getExpandRatio()); + final int expandRatio = defaultExpandRatios ? 1 + : column.getExpandRatio(); final double maxWidth = getMaxWidth(column); final double newWidth = Math.min(maxWidth, column.getWidthActual()); @@ -3473,8 +3530,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, boolean hasAutoWidth = column.getWidth() < 0; if (hasAutoWidth && currentWidth < minWidth) { columnSizes.put(columnIndex, minWidth); - pixelsToRemoveFromOtherColumns += (minWidth - - currentWidth); + pixelsToRemoveFromOtherColumns += minWidth + - currentWidth; minWidthsCausedReflows = true; /* @@ -3570,7 +3627,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private static final String STRIPE_CLASSNAME = "stripe"; - private final Map<Element, Widget> elementToWidgetMap = new HashMap<>(); + private final Map<Element, Widget> elementToWidgetMap = new HashMap<Element, Widget>(); @Override public void init(Spacer spacer) { @@ -3893,7 +3950,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, .getFirstChildElement(); double height = WidgetUtil .getRequiredHeightBoundingClientRectDouble(firstHeaderCell) - - (WidgetUtil.measureVerticalBorder(getElement()) / 2); + - WidgetUtil.measureVerticalBorder(getElement()) / 2; openCloseButton.setHeight(height + "px"); } @@ -3952,7 +4009,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private final class ColumnHider { /** Map from columns to their hiding toggles, component might change */ - private HashMap<Column<?, T>, MenuItem> columnToHidingToggleMap = new HashMap<>(); + private HashMap<Column<?, T>, MenuItem> columnToHidingToggleMap = new HashMap<Column<?, T>, MenuItem>(); /** * When column is being hidden with a toggle, do not refresh toggles for @@ -3969,7 +4026,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, toggle.setStyleName("hidden", column.isHidden()); } else if (columnToHidingToggleMap.containsKey(column)) { sidebar.menuBar - .removeItem((columnToHidingToggleMap.remove(column))); + .removeItem(columnToHidingToggleMap.remove(column)); } updateTogglesOrder(); } @@ -4051,7 +4108,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, /** * List of columns in the grid. Order defines the visible order. */ - private List<Column<?, T>> columns = new ArrayList<>(); + private List<Column<?, T>> columns = new ArrayList<Column<?, T>>(); /** * The datasource currently in use. <em>Note:</em> it is <code>null</code> @@ -4075,7 +4132,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * Current sort order. The (private) sort() method reads this list to * determine the order in which to present rows. */ - private List<SortOrder> sortOrder = new ArrayList<>(); + private List<SortOrder> sortOrder = new ArrayList<SortOrder>(); private Renderer<Boolean> selectColumnRenderer = null; @@ -4127,9 +4184,9 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private DetailsGenerator detailsGenerator = DetailsGenerator.NULL; private GridSpacerUpdater gridSpacerUpdater = new GridSpacerUpdater(); /** A set keeping track of the indices of all currently open details */ - private Set<Integer> visibleDetails = new HashSet<>(); + private Set<Integer> visibleDetails = new HashSet<Integer>(); /** A set of indices of details to reopen after detach and on attach */ - private final Set<Integer> reattachVisibleDetails = new HashSet<>(); + private final Set<Integer> reattachVisibleDetails = new HashSet<Integer>(); private boolean columnReorderingAllowed; @@ -4181,7 +4238,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * Map of possible drop positions for the column and the corresponding * column index. */ - private final TreeMap<Double, Integer> possibleDropPositions = new TreeMap<>(); + private final TreeMap<Double, Integer> possibleDropPositions = new TreeMap<Double, Integer>(); /** * Makes sure that drag cancel doesn't cause anything unwanted like sort */ @@ -4377,10 +4434,9 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, final int colspan = header.getRow(eventCell.getRowIndex()) .getCell(eventCell.getColumn()).getColspan(); if (latestColumnDropIndex != draggedColumnIndex - && latestColumnDropIndex != (draggedColumnIndex - + colspan)) { + && latestColumnDropIndex != draggedColumnIndex + colspan) { List<Column<?, T>> columns = getColumns(); - List<Column<?, T>> reordered = new ArrayList<>(); + List<Column<?, T>> reordered = new ArrayList<Column<?, T>>(); if (draggedColumnIndex < latestColumnDropIndex) { reordered.addAll(columns.subList(0, draggedColumnIndex)); reordered.addAll( @@ -4399,12 +4455,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, reordered.addAll(columns.subList( draggedColumnIndex + colspan, columns.size())); } - reordered.remove(selectionColumn); // since - // setColumnOrder - // will - // add - // it - // anyway! + reordered.remove(selectionColumn); // since setColumnOrder will + // add it anyway! // capture focused cell column before reorder Cell focusedCell = cellFocusHandler.getFocusedCell(); @@ -4418,9 +4470,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, .toArray(new Column[reordered.size()]); setColumnOrder(array); transferCellFocusOnDrop(); - } // else - // no - // reordering + } // else no reordering } private void transferCellFocusOnDrop() { @@ -4514,8 +4564,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, int leftBound = -1; int rightBound = getColumnCount() + 1; - final HashSet<Integer> unavailableColumnDropIndices = new HashSet<>(); - final List<StaticRow<?>> rows = new ArrayList<>(); + final HashSet<Integer> unavailableColumnDropIndices = new HashSet<Integer>(); + final List<StaticRow<?>> rows = new ArrayList<StaticRow<?>>(); rows.addAll(header.getRows()); rows.addAll(footer.getRows()); for (StaticRow<?> row : rows) { @@ -4573,7 +4623,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } } - if (leftBound == (rightBound - 1)) { + if (leftBound == rightBound - 1) { return; } @@ -5101,7 +5151,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, grid.header.updateColSpans(); grid.footer.updateColSpans(); scheduleColumnWidthRecalculator(); - this.grid.fireEvent(new ColumnVisibilityChangeEvent<>(this, + this.grid.fireEvent(new ColumnVisibilityChangeEvent<T>(this, hidden, userOriginated)); } } @@ -5495,7 +5545,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, setStyleName(rowElement, rowHasDataStyleName, hasData); } - boolean isEvenIndex = (row.getRow() % 2 == 0); + boolean isEvenIndex = row.getRow() % 2 == 0; setStyleName(rowElement, rowStripeStyleName, !isEvenIndex); rowReference.set(rowIndex, rowData, rowElement); @@ -5766,7 +5816,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, if (c.getWidth() < 0) { c.setWidth(c.getWidthActual()); - fireEvent(new ColumnResizeEvent<>(c)); + fireEvent(new ColumnResizeEvent<T>(c)); } } @@ -5821,7 +5871,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, dragEnded(); col.setWidth(width); - fireEvent(new ColumnResizeEvent<>(col)); + fireEvent(new ColumnResizeEvent<T>(col)); } }; @@ -5848,7 +5898,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, public void onComplete() { dragEnded(); col.setWidth(width); - fireEvent(new ColumnResizeEvent<>(col)); + fireEvent(new ColumnResizeEvent<T>(col)); } }; @@ -5958,7 +6008,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, escalator.getColumnConfiguration().setColumnWidth(colIndex, minWidth); - fireEvent(new ColumnResizeEvent<>(column)); + fireEvent(new ColumnResizeEvent<T>(column)); } } @@ -6128,7 +6178,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, new RendererEventHandler(), // Moving cell focus by keyboard or mouse new CellFocusEventHandler())); - } @Override @@ -6136,29 +6185,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, return enabled; } - /** - * Sets the column resize mode to use. The default mode is - * {@link ColumnResizeMode.ANIMATED}. - * - * @param mode - * a ColumnResizeMode value - * @since 7.7.5 - */ - public void setColumnResizeMode(ColumnResizeMode mode) { - columnResizeMode = mode; - } - - /** - * Returns the current column resize mode. The default mode is - * {@link ColumnResizeMode.ANIMATED}. - * - * @return a ColumnResizeMode value - * @since 7.7.5 - */ - public ColumnResizeMode getColumnResizeMode() { - return columnResizeMode; - } - @Override public void setEnabled(boolean enabled) { if (enabled == this.enabled) { @@ -6207,6 +6233,29 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } /** + * Sets the column resize mode to use. The default mode is + * {@link ColumnResizeMode.ANIMATED}. + * + * @param mode + * a ColumnResizeMode value + * @since 7.7.5 + */ + public void setColumnResizeMode(ColumnResizeMode mode) { + columnResizeMode = mode; + } + + /** + * Returns the current column resize mode. The default mode is + * {@link ColumnResizeMode.ANIMATED}. + * + * @return a ColumnResizeMode value + * @since 7.7.5 + */ + public ColumnResizeMode getColumnResizeMode() { + return columnResizeMode; + } + + /** * Creates the escalator updater used to update the header rows in this * grid. The updater is invoked when header rows or columns are added or * removed, or the content of existing header cells is changed. @@ -6279,21 +6328,22 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * * @param rowIndex * index of row to focus - * @param columnIndex - * index of cell to focus + * @param columnIndexDOM + * index (excluding hidden columns) of cell to focus */ - void focusCell(int rowIndex, int columnIndex) { + void focusCell(int rowIndex, int columnIndexDOM) { final Range rowRange = Range.between(0, dataSource.size()); final Range columnRange = Range.between(0, getVisibleColumns().size()); assert rowRange.contains( rowIndex) : "Illegal row index. Should be in range " + rowRange; assert columnRange.contains( - columnIndex) : "Illegal column index. Should be in range " + columnIndexDOM) : "Illegal column index. Should be in range " + columnRange; - if (rowRange.contains(rowIndex) && columnRange.contains(columnIndex)) { - cellFocusHandler.setCellFocus(rowIndex, columnIndex, + if (rowRange.contains(rowIndex) + && columnRange.contains(columnIndexDOM)) { + cellFocusHandler.setCellFocus(rowIndex, columnIndexDOM, escalator.getBody()); WidgetUtil.focus(getElement()); } @@ -6398,7 +6448,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, column.reapplyWidth(); // Sink all renderer events - Set<String> events = new HashSet<>(); + Set<String> events = new HashSet<String>(); events.addAll(getConsumedEventsForRenderer(column.getRenderer())); if (column.isHidable()) { @@ -6496,7 +6546,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * @return A unmodifiable list of the columns in the grid */ public List<Column<?, T>> getColumns() { - return Collections.unmodifiableList(new ArrayList<>(columns)); + return Collections + .unmodifiableList(new ArrayList<Column<?, T>>(columns)); } /** @@ -6508,7 +6559,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * @return A unmodifiable list of the currently visible columns in the grid */ public List<Column<?, T>> getVisibleColumns() { - ArrayList<Column<?, T>> visible = new ArrayList<>(); + ArrayList<Column<?, T>> visible = new ArrayList<Column<?, T>>(); for (Column<?, T> c : columns) { if (!c.isHidden()) { visible.add(c); @@ -6535,13 +6586,13 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, return columns.get(index); } - private Column<?, T> getVisibleColumn(int index) + private Column<?, T> getVisibleColumn(int columnIndexDOM) throws IllegalArgumentException { List<Column<?, T>> visibleColumns = getVisibleColumns(); - if (index < 0 || index >= visibleColumns.size()) { + if (columnIndexDOM < 0 || columnIndexDOM >= visibleColumns.size()) { throw new IllegalStateException("Column not found."); } - return visibleColumns.get(index); + return visibleColumns.get(columnIndexDOM); } /** @@ -6928,7 +6979,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, int oldSize = body.getRowCount(); // Hide all details. - Set<Integer> oldDetails = new HashSet<>(visibleDetails); + Set<Integer> oldDetails = new HashSet<Integer>( + visibleDetails); for (int i : oldDetails) { setDetailsVisible(i, false); } @@ -7300,7 +7352,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } private Set<String> getConsumedEventsForRenderer(Renderer<?> renderer) { - Set<String> events = new HashSet<>(); + Set<String> events = new HashSet<String>(); if (renderer instanceof ComplexRenderer) { Collection<String> consumedEvents = ((ComplexRenderer<?>) renderer) .getConsumedEvents(); @@ -7386,7 +7438,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, + "-event with a null cell target"; eventCell.set(cell, getSectionFromContainer(container)); - GridEvent<T> gridEvent = new GridEvent<>(event, eventCell); + GridEvent<T> gridEvent = new GridEvent<T>(event, eventCell); for (GridEventHandler<T> handler : browserEventHandlers) { handler.onEvent(gridEvent); } @@ -7450,13 +7502,14 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } Widget widget; - if (editor.focusedColumnIndex < 0) { + if (editor.focusedColumnIndexDOM < 0) { widget = null; } else { - widget = editor.getWidget(getColumn(editor.focusedColumnIndex)); + widget = editor.getWidget( + getVisibleColumn(editor.focusedColumnIndexDOM)); } - EditorDomEvent<T> editorEvent = new EditorDomEvent<>( + EditorDomEvent<T> editorEvent = new EditorDomEvent<T>( event.getDomEvent(), event.getCell(), widget); event.setHandled( @@ -7559,8 +7612,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, if (!event.getCell().isHeader()) { return; } - if (event.getCell().getColumnIndex() < escalator - .getColumnConfiguration().getFrozenColumnCount()) { + if (event.getCell().getColumnIndex() < getFrozenColumnCount()) { return; } @@ -7939,8 +7991,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, /** * Deselect all rows using the current selection model. * - * @param row - * a row object * @return <code>true</code> iff the current selection changed * @throws IllegalStateException * if the current selection model is not an instance of @@ -7948,7 +7998,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public boolean deselectAll() { if (selectionModel instanceof SelectionModel.Single<?>) { - Single<T> single = ((SelectionModel.Single<T>) selectionModel); + Single<T> single = (SelectionModel.Single<T>) selectionModel; if (single.getSelectedRow() != null) { return single.deselect(single.getSelectedRow()); } else { @@ -8418,8 +8468,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ private void sort(boolean userOriginated) { refreshHeader(); - fireEvent(new SortEvent<>(this, Collections.unmodifiableList(sortOrder), - userOriginated)); + fireEvent(new SortEvent<T>(this, + Collections.unmodifiableList(sortOrder), userOriginated)); } private int getLastVisibleRowIndex() { @@ -8500,7 +8550,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, // Trigger ComplexRenderer.destroy for old content conf.removeColumns(0, conf.getColumnCount()); - List<Column<?, T>> newOrder = new ArrayList<>(); + List<Column<?, T>> newOrder = new ArrayList<Column<?, T>>(); if (selectionColumn != null) { newOrder.add(selectionColumn); } @@ -8774,11 +8824,15 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, // Grid was just attached to DOM. Column widths should be calculated. recalculateColumnWidths(); + for (int row : reattachVisibleDetails) { + setDetailsVisible(row, true); + } + reattachVisibleDetails.clear(); } @Override protected void onDetach() { - Set<Integer> details = new HashSet<>(visibleDetails); + Set<Integer> details = new HashSet<Integer>(visibleDetails); reattachVisibleDetails.clear(); reattachVisibleDetails.addAll(details); for (int row : details) { @@ -9190,11 +9244,28 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, if (container != null) { Cell cell = container.getCell(element); if (cell != null) { - EventCellReference<T> cellRef = new EventCellReference<>(this); + EventCellReference<T> cellRef = new EventCellReference<T>(this); cellRef.set(cell, getSectionFromContainer(container)); return cellRef; } } return null; } + + /** + * Checks if selection by the user is allowed in the grid. + * + * @return <code>true</code> if selection by the user is allowed by the + * selection model (the default), <code>false</code> otherwise + * @since 7.7.7 + */ + public boolean isUserSelectionAllowed() { + if (!(getSelectionModel() instanceof HasUserSelectionAllowed)) { + // Selection model does not support toggling user selection allowed + // - old default is to always allow selection + return true; + } + return ((HasUserSelectionAllowed) getSelectionModel()) + .isUserSelectionAllowed(); + } } |