Fixes #8011tags/7.7.7
import com.google.gwt.dom.client.Element; | import com.google.gwt.dom.client.Element; | ||||
import com.google.gwt.dom.client.NativeEvent; | import com.google.gwt.dom.client.NativeEvent; | ||||
import com.google.gwt.dom.client.TableElement; | import com.google.gwt.dom.client.TableElement; | ||||
import com.google.gwt.dom.client.TableRowElement; | |||||
import com.google.gwt.dom.client.TableSectionElement; | import com.google.gwt.dom.client.TableSectionElement; | ||||
import com.google.gwt.event.dom.client.ClickEvent; | import com.google.gwt.event.dom.client.ClickEvent; | ||||
import com.google.gwt.event.dom.client.ClickHandler; | import com.google.gwt.event.dom.client.ClickHandler; | ||||
import com.vaadin.client.widget.grid.events.GridEnabledEvent; | import com.vaadin.client.widget.grid.events.GridEnabledEvent; | ||||
import com.vaadin.client.widget.grid.events.GridEnabledHandler; | import com.vaadin.client.widget.grid.events.GridEnabledHandler; | ||||
import com.vaadin.client.widget.grid.selection.SelectionModel.Multi.Batched; | import com.vaadin.client.widget.grid.selection.SelectionModel.Multi.Batched; | ||||
import com.vaadin.client.widgets.Escalator.AbstractRowContainer; | |||||
import com.vaadin.client.widgets.Grid; | import com.vaadin.client.widgets.Grid; | ||||
/** | /** | ||||
int constrainedPageY = Math.max(bodyAbsoluteTop, | int constrainedPageY = Math.max(bodyAbsoluteTop, | ||||
Math.min(bodyAbsoluteBottom, pageY)); | Math.min(bodyAbsoluteBottom, pageY)); | ||||
int logicalRow = getLogicalRowIndex(WidgetUtil | |||||
int logicalRow = getLogicalRowIndex(grid, WidgetUtil | |||||
.getElementFromPoint(initialPageX, constrainedPageY)); | .getElementFromPoint(initialPageX, constrainedPageY)); | ||||
int incrementOrDecrement = (logicalRow > lastModifiedLogicalRow) ? 1 | int incrementOrDecrement = (logicalRow > lastModifiedLogicalRow) ? 1 | ||||
} | } | ||||
} | } | ||||
private static final String LOGICAL_ROW_PROPERTY_INT = "vEscalatorLogicalRow"; | |||||
private final Grid<T> grid; | private final Grid<T> grid; | ||||
private HandlerRegistration nativePreviewHandlerRegistration; | private HandlerRegistration nativePreviewHandlerRegistration; | ||||
CheckBox checkBox) { | CheckBox checkBox) { | ||||
checkBox.setValue(data, false); | checkBox.setValue(data, false); | ||||
checkBox.setEnabled(grid.isEnabled() && !grid.isEditorActive()); | checkBox.setEnabled(grid.isEnabled() && !grid.isEditorActive()); | ||||
checkBox.getElement().setPropertyInt(LOGICAL_ROW_PROPERTY_INT, | |||||
cell.getRowIndex()); | |||||
} | } | ||||
@Override | @Override | ||||
private void startDragSelect(NativeEvent event, final Element target) { | private void startDragSelect(NativeEvent event, final Element target) { | ||||
injectNativeHandler(); | injectNativeHandler(); | ||||
int logicalRowIndex = getLogicalRowIndex(target); | |||||
int logicalRowIndex = getLogicalRowIndex(grid, target); | |||||
autoScrollHandler.start(logicalRowIndex); | autoScrollHandler.start(logicalRowIndex); | ||||
event.preventDefault(); | event.preventDefault(); | ||||
event.stopPropagation(); | event.stopPropagation(); | ||||
} | } | ||||
} | } | ||||
private int getLogicalRowIndex(final Element target) { | |||||
private int getLogicalRowIndex(Grid<T> grid, final Element target) { | |||||
if (target == null) { | if (target == null) { | ||||
return -1; | return -1; | ||||
} | } | ||||
final Element checkbox = td.getFirstChildElement(); | final Element checkbox = td.getFirstChildElement(); | ||||
assert checkbox != null : "Checkbox has disappeared"; | assert checkbox != null : "Checkbox has disappeared"; | ||||
return checkbox.getPropertyInt(LOGICAL_ROW_PROPERTY_INT); | |||||
return ((AbstractRowContainer) grid.getEscalator().getBody()) | |||||
.getLogicalRowIndex((TableRowElement) tr); | |||||
} | } | ||||
tr = tr.getNextSiblingElement(); | tr = tr.getNextSiblingElement(); | ||||
} | } |
import com.google.gwt.dom.client.Touch; | import com.google.gwt.dom.client.Touch; | ||||
import com.google.gwt.event.shared.HandlerRegistration; | import com.google.gwt.event.shared.HandlerRegistration; | ||||
import com.google.gwt.logging.client.LogConfiguration; | import com.google.gwt.logging.client.LogConfiguration; | ||||
import com.google.gwt.user.client.Command; | |||||
import com.google.gwt.user.client.DOM; | import com.google.gwt.user.client.DOM; | ||||
import com.google.gwt.user.client.Window; | import com.google.gwt.user.client.Window; | ||||
import com.google.gwt.user.client.ui.RequiresResize; | import com.google.gwt.user.client.ui.RequiresResize; | ||||
if (isCurrentBrowserIE11OrEdge()) { | if (isCurrentBrowserIE11OrEdge()) { | ||||
return vertical | return vertical | ||||
? event.getNativeEvent().getClientY() | ? event.getNativeEvent().getClientY() | ||||
+ Window.getScrollTop() | |||||
+ Window.getScrollTop() | |||||
: event.getNativeEvent().getClientX() | : event.getNativeEvent().getClientX() | ||||
+ Window.getScrollLeft(); | |||||
+ Window.getScrollLeft(); | |||||
} | } | ||||
JsArray<Touch> a = event.getNativeEvent().getTouches(); | JsArray<Touch> a = event.getNativeEvent().getTouches(); | ||||
return vertical ? a.get(0).getPageY() : a.get(0).getPageX(); | return vertical ? a.get(0).getPageY() : a.get(0).getPageX(); | ||||
// (#18737), | // (#18737), | ||||
// otherwise allow touch only if there is a single touch in the | // otherwise allow touch only if there is a single touch in the | ||||
// event | // event | ||||
private boolean allowTouch(final TouchHandlerBundle.CustomTouchEvent event) { | |||||
private boolean allowTouch( | |||||
final TouchHandlerBundle.CustomTouchEvent event) { | |||||
if (isCurrentBrowserIE11OrEdge()) { | if (isCurrentBrowserIE11OrEdge()) { | ||||
return (POINTER_EVENT_TYPE_TOUCH.equals(event.getPointerType())); | |||||
return (POINTER_EVENT_TYPE_TOUCH | |||||
.equals(event.getPointerType())); | |||||
} else { | } else { | ||||
return (event.getNativeEvent().getTouches().length() == 1); | return (event.getNativeEvent().getTouches().length() == 1); | ||||
} | } | ||||
}-*/; | }-*/; | ||||
/** | /** | ||||
* Using pointerdown, pointermove, pointerup, and pointercancel for IE11 and Edge instead of | |||||
* touch* listeners (#18737) | |||||
* Using pointerdown, pointermove, pointerup, and pointercancel for IE11 | |||||
* and Edge instead of touch* listeners (#18737) | |||||
* | * | ||||
* @param element | * @param element | ||||
*/ | */ | ||||
}-*/; | }-*/; | ||||
/** | /** | ||||
* Using pointerdown, pointermove, pointerup, and pointercancel for IE11 and Edge instead of | |||||
* touch* listeners (#18737) | |||||
* Using pointerdown, pointermove, pointerup, and pointercancel for IE11 | |||||
* and Edge instead of touch* listeners (#18737) | |||||
* | * | ||||
* @param element | * @param element | ||||
*/ | */ | ||||
} | } | ||||
} | } | ||||
protected abstract class AbstractRowContainer implements RowContainer { | |||||
public abstract class AbstractRowContainer implements RowContainer { | |||||
private EscalatorUpdater updater = EscalatorUpdater.NULL; | private EscalatorUpdater updater = EscalatorUpdater.NULL; | ||||
private int rows; | private int rows; | ||||
*/ | */ | ||||
protected abstract double getHeightOfSection(); | protected abstract double getHeightOfSection(); | ||||
protected int getLogicalRowIndex(final TableRowElement tr) { | |||||
/** | |||||
* Gets the logical row index for the given table row element. | |||||
* | |||||
* @param tr | |||||
* the table row element inside this container. | |||||
* @return the logical index of the given element | |||||
*/ | |||||
public int getLogicalRowIndex(final TableRowElement tr) { | |||||
return tr.getSectionRowIndex(); | return tr.getSectionRowIndex(); | ||||
}; | }; | ||||
} | } | ||||
@Override | @Override | ||||
protected int getLogicalRowIndex(final TableRowElement tr) { | |||||
public int getLogicalRowIndex(final TableRowElement tr) { | |||||
assert tr | assert tr | ||||
.getParentNode() == root : "The given element isn't a row element in the body"; | .getParentNode() == root : "The given element isn't a row element in the body"; | ||||
int internalIndex = visualRowOrder.indexOf(tr); | int internalIndex = visualRowOrder.indexOf(tr); | ||||
/** | /** | ||||
* Internal method for checking whether the browser is IE11 or Edge | * Internal method for checking whether the browser is IE11 or Edge | ||||
* | |||||
* @return true only if the current browser is IE11, or Edge | * @return true only if the current browser is IE11, or Edge | ||||
*/ | */ | ||||
private static boolean isCurrentBrowserIE11OrEdge() { | private static boolean isCurrentBrowserIE11OrEdge() { |
public void onStart() { | public void onStart() { | ||||
dragStarted(); | dragStarted(); | ||||
dragger.getElement().appendChild(resizeElement); | dragger.getElement().appendChild(resizeElement); | ||||
resizeElement.getStyle() | |||||
.setLeft((dragger.getElement() | |||||
.getOffsetWidth() | |||||
resizeElement.getStyle().setLeft( | |||||
(dragger.getElement().getOffsetWidth() | |||||
- resizeElement.getOffsetWidth()) | - resizeElement.getOffsetWidth()) | ||||
* .5, Unit.PX); | |||||
* .5, | |||||
Unit.PX); | |||||
resizeElement.getStyle().setHeight( | resizeElement.getStyle().setHeight( | ||||
col.grid.getOffsetHeight(), Unit.PX); | col.grid.getOffsetHeight(), Unit.PX); | ||||
} | } | ||||
return editor; | return editor; | ||||
} | } | ||||
protected Escalator getEscalator() { | |||||
/** | |||||
* Gets the {@link Escalator} used by this Grid instnace. | |||||
* | |||||
* @return the escalator instance, never <code>null</code> | |||||
*/ | |||||
public Escalator getEscalator() { | |||||
return escalator; | return escalator; | ||||
} | } | ||||
import static org.junit.Assert.assertFalse; | import static org.junit.Assert.assertFalse; | ||||
import static org.junit.Assert.assertTrue; | import static org.junit.Assert.assertTrue; | ||||
import java.util.Arrays; | |||||
import java.util.HashSet; | |||||
import org.junit.Assert; | |||||
import org.junit.Test; | import org.junit.Test; | ||||
import org.openqa.selenium.Keys; | import org.openqa.selenium.Keys; | ||||
import org.openqa.selenium.WebDriver; | import org.openqa.selenium.WebDriver; | ||||
import com.vaadin.testbench.elements.GridElement.GridRowElement; | import com.vaadin.testbench.elements.GridElement.GridRowElement; | ||||
import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures; | import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures; | ||||
import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; | import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; | ||||
import com.vaadin.tests.components.grid.basicfeatures.element.CustomGridElement; | |||||
public class GridSelectionTest extends GridBasicFeaturesTest { | public class GridSelectionTest extends GridBasicFeaturesTest { | ||||
"Exception occured, java.lang.NullPointerException: null")); | "Exception occured, java.lang.NullPointerException: null")); | ||||
} | } | ||||
@Test | |||||
public void testRemoveSelectedRowMulti() { | |||||
openTestURL(); | |||||
setSelectionModelMulti(); | |||||
CustomGridElement grid = getGridElement(); | |||||
grid.getCell(5, 0).click(); | |||||
selectMenuPath("Component", "Body rows", "Remove selected rows"); | |||||
assertSelected(); | |||||
grid.getCell(5, 0).click(); | |||||
assertSelected(5); | |||||
grid.getCell(6, 0).click(); | |||||
assertSelected(5, 6); | |||||
grid.getCell(5, 0).click(); | |||||
assertSelected(6); | |||||
grid.getCell(5, 0).click(); | |||||
grid.getCell(4, 0).click(); | |||||
selectMenuPath("Component", "Body rows", "Remove selected rows"); | |||||
assertSelected(); | |||||
grid.getCell(0, 0).click(); | |||||
assertSelected(0); | |||||
grid.getCell(5, 0).click(); | |||||
assertSelected(0, 5); | |||||
grid.getCell(6, 0).click(); | |||||
assertSelected(0, 5, 6); | |||||
} | |||||
private void assertSelected(Integer... selected) { | |||||
CustomGridElement grid = getGridElement(); | |||||
HashSet<Integer> expected = new HashSet<Integer>( | |||||
Arrays.asList(selected)); | |||||
for (int i = 0; i < 10; i++) { | |||||
boolean rowSelected = grid.getRow(i).isSelected(); | |||||
if (expected.contains(i)) { | |||||
Assert.assertTrue("Expected row " + i + " to be selected", | |||||
rowSelected); | |||||
} else { | |||||
Assert.assertFalse("Expected row " + i + " not to be selected", | |||||
rowSelected); | |||||
} | |||||
} | |||||
} | |||||
private void waitUntilCheckBoxValue(final WebElement checkBoxElememnt, | private void waitUntilCheckBoxValue(final WebElement checkBoxElememnt, | ||||
final boolean expectedValue) { | final boolean expectedValue) { | ||||
waitUntil(new ExpectedCondition<Boolean>() { | waitUntil(new ExpectedCondition<Boolean>() { |