aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceExtensionConnector.java4
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetExtensionConnector.java119
-rw-r--r--client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java2
-rw-r--r--client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java101
-rw-r--r--server/src/main/java/com/vaadin/event/dnd/DropTargetExtension.java15
-rw-r--r--server/src/main/java/com/vaadin/event/dnd/grid/GridDropEvent.java67
-rw-r--r--server/src/main/java/com/vaadin/event/dnd/grid/GridDropListener.java46
-rw-r--r--server/src/main/java/com/vaadin/ui/GridDropTargetExtension.java72
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/grid/GridDragSourceExtensionState.java5
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/grid/GridDropTargetExtensionRpc.java39
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/grid/GridDropTargetExtensionState.java28
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/grid/GridDragAndDrop.java31
-rw-r--r--uitest/src/main/java/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java9
13 files changed, 485 insertions, 53 deletions
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceExtensionConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceExtensionConnector.java
index eaeaffc1d9..b31a2578eb 100644
--- a/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceExtensionConnector.java
+++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceExtensionConnector.java
@@ -29,6 +29,7 @@ import com.vaadin.client.widgets.Escalator;
import com.vaadin.client.widgets.Grid;
import com.vaadin.shared.Range;
import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.dnd.DragSourceState;
import com.vaadin.shared.ui.grid.GridDragSourceExtensionState;
import com.vaadin.ui.GridDragSourceExtension;
@@ -83,8 +84,7 @@ public class GridDragSourceExtensionConnector extends
// Set drag data in DataTransfer object
((NativeEvent) event).getDataTransfer()
- .setData(GridDragSourceExtensionState.DATA_TYPE_DRAG_DATA,
- dragData.toJson());
+ .setData(DragSourceState.DATA_TYPE_TEXT, dragData.toJson());
}
}
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetExtensionConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetExtensionConnector.java
new file mode 100644
index 0000000000..9c25f5acb4
--- /dev/null
+++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetExtensionConnector.java
@@ -0,0 +1,119 @@
+/*
+ * 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.client.connectors.grid;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.TableRowElement;
+import com.vaadin.client.ServerConnector;
+import com.vaadin.client.extensions.DropTargetExtensionConnector;
+import com.vaadin.client.widget.escalator.RowContainer;
+import com.vaadin.client.widgets.Escalator;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.grid.GridDropTargetExtensionRpc;
+import com.vaadin.shared.ui.grid.GridDropTargetExtensionState;
+import com.vaadin.shared.ui.grid.GridState;
+import com.vaadin.ui.GridDropTargetExtension;
+
+import elemental.events.Event;
+import elemental.json.JsonObject;
+
+/**
+ * Makes Grid an HTML5 drop target. This is the client side counterpart of
+ * {@link GridDropTargetExtension}.
+ *
+ * @author Vaadin Ltd
+ * @since
+ */
+@Connect(GridDropTargetExtension.class)
+public class GridDropTargetExtensionConnector extends
+ DropTargetExtensionConnector {
+
+ private GridConnector gridConnector;
+
+ @Override
+ protected void extend(ServerConnector target) {
+ gridConnector = (GridConnector) target;
+
+ super.extend(target);
+ }
+
+ @Override
+ protected void sendDropEventToServer(String dataTransferText,
+ Event dropEvent) {
+
+ String rowKey = null;
+ Optional<TableRowElement> targetRow = getTargetRow(
+ (Element) dropEvent.getTarget());
+ if (targetRow.isPresent()) {
+ rowKey = getRowData(targetRow.get())
+ .getString(GridState.JSONKEY_ROWKEY);
+ }
+
+ getRpcProxy(GridDropTargetExtensionRpc.class)
+ .drop(dataTransferText, rowKey);
+ }
+
+ private JsonObject getRowData(TableRowElement row) {
+ int rowIndex = ((Escalator.AbstractRowContainer) getGridBody())
+ .getLogicalRowIndex(row);
+ return gridConnector.getDataSource().getRow(rowIndex);
+ }
+
+ @Override
+ protected void addTargetIndicator(Event event) {
+ getTargetRow(((Element) event.getTarget()))
+ .ifPresent(e -> e.addClassName(CLASS_DRAG_OVER));
+ }
+
+ @Override
+ protected void removeTargetIndicator(Event event) {
+ getTargetRow(((Element) event.getTarget()))
+ .ifPresent(e -> e.removeClassName(CLASS_DRAG_OVER));
+ }
+
+ private Optional<TableRowElement> getTargetRow(Element source) {
+ while (!Objects.equals(source, getGridBody().getElement())) {
+ if (TableRowElement.is(source)) {
+ return Optional.of(source.cast());
+ }
+ source = source.getParentElement();
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ protected Element getDropTargetElement() {
+ return getGridBody().getElement();
+ }
+
+ private Escalator getEscalator() {
+ return gridConnector.getWidget().getEscalator();
+ }
+
+ private RowContainer.BodyRowContainer getGridBody() {
+ return getEscalator().getBody();
+ }
+
+ @Override
+ public GridDropTargetExtensionState getState() {
+ return (GridDropTargetExtensionState) super.getState();
+ }
+}
diff --git a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
index 23797ce886..52c70b362b 100644
--- a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
+++ b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
@@ -161,7 +161,7 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector {
((NativeEvent) event).getDataTransfer());
assert dropEffect != null : "Drop effect should never be null";
-
+
getRpcProxy(DragSourceRpc.class)
.dragEnd(DropEffect.valueOf(dropEffect.toUpperCase()));
}
diff --git a/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java b/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java
index 5f8ca243c7..473b72237e 100644
--- a/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java
+++ b/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java
@@ -15,7 +15,6 @@
*/
package com.vaadin.client.extensions;
-import com.google.gwt.dom.client.BrowserEvents;
import com.google.gwt.dom.client.DataTransfer;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
@@ -42,7 +41,7 @@ import elemental.events.EventTarget;
@Connect(DropTargetExtension.class)
public class DropTargetExtensionConnector extends AbstractExtensionConnector {
- private static final String CLASS_DRAG_OVER = "v-drag-over";
+ protected static final String CLASS_DRAG_OVER = "v-drag-over";
// Create event listeners
private final EventListener dragEnterListener = this::onDragEnter;
@@ -59,35 +58,46 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
protected void extend(ServerConnector target) {
dropTargetWidget = ((ComponentConnector) target).getWidget();
- EventTarget dropTarget = getDropTargetElement().cast();
+ addDropListeners(getDropTargetElement());
+ }
- // dragenter event
- dropTarget.addEventListener(BrowserEvents.DRAGENTER, dragEnterListener);
+ /**
+ * Adds dragenter, dragover, dragleave and drop event listeners to the given
+ * DOM element.
+ *
+ * @param element
+ * DOM element to attach event listeners to.
+ */
+ protected void addDropListeners(Element element) {
+ EventTarget target = element.cast();
- // dragover event
- dropTarget.addEventListener(BrowserEvents.DRAGOVER, dragOverListener);
+ target.addEventListener(Event.DRAGENTER, dragEnterListener);
+ target.addEventListener(Event.DRAGOVER, dragOverListener);
+ target.addEventListener(Event.DRAGLEAVE, dragLeaveListener);
+ target.addEventListener(Event.DROP, dropListener);
+ }
- // dragleave event
- dropTarget.addEventListener(BrowserEvents.DRAGLEAVE, dragLeaveListener);
+ /**
+ * Removes dragenter, dragover, dragleave and drop event listeners from the
+ * given DOM element.
+ *
+ * @param element
+ * DOM element to remove event listeners from.
+ */
+ protected void removeDropListeners(Element element) {
+ EventTarget target = element.cast();
- // drop event
- dropTarget.addEventListener(BrowserEvents.DROP, dropListener);
+ target.removeEventListener(Event.DRAGENTER, dragEnterListener);
+ target.removeEventListener(Event.DRAGOVER, dragOverListener);
+ target.removeEventListener(Event.DRAGLEAVE, dragLeaveListener);
+ target.removeEventListener(Event.DROP, dropListener);
}
@Override
public void onUnregister() {
super.onUnregister();
- EventTarget dropTarget = getDropTargetElement().cast();
-
- // Remove listeners
- dropTarget.removeEventListener(BrowserEvents.DRAGENTER,
- dragEnterListener);
- dropTarget.removeEventListener(BrowserEvents.DRAGOVER,
- dragOverListener);
- dropTarget.removeEventListener(BrowserEvents.DRAGLEAVE,
- dragLeaveListener);
- dropTarget.removeEventListener(BrowserEvents.DROP, dropListener);
+ removeDropListeners(getDropTargetElement());
}
/**
@@ -107,7 +117,7 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
* browser event to be handled
*/
protected void onDragEnter(Event event) {
- addTargetIndicator(getDropTargetElement());
+ addTargetIndicator(event);
}
/**
@@ -126,6 +136,9 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
.valueOf(getState().dropEffect.name()));
}
+ // Add drop target indicator in case the element doesn't have one
+ addTargetIndicator(event);
+
// Prevent default to allow drop
nativeEvent.preventDefault();
nativeEvent.stopPropagation();
@@ -135,7 +148,7 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
.setDropEffect(DataTransfer.DropEffect.NONE);
// Remove drop target indicator
- removeTargetIndicator(getDropTargetElement());
+ removeTargetIndicator(event);
}
}
@@ -164,7 +177,7 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
* browser event to be handled
*/
protected void onDragLeave(Event event) {
- removeTargetIndicator(getDropTargetElement());
+ removeTargetIndicator(event);
}
/**
@@ -182,10 +195,10 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
String dataTransferText = nativeEvent.getDataTransfer().getData(
DragSourceState.DATA_TYPE_TEXT);
- getRpcProxy(DropTargetRpc.class).drop(dataTransferText);
+ sendDropEventToServer(dataTransferText, event);
}
- removeTargetIndicator(getDropTargetElement());
+ removeTargetIndicator(event);
}
private boolean dropAllowed(NativeEvent event) {
@@ -197,12 +210,40 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
return true;
}
- private void addTargetIndicator(Element element) {
- element.addClassName(CLASS_DRAG_OVER);
+ /**
+ * Initiates a server RPC for the drop event.
+ *
+ * @param dataTransferText
+ * Client side textual data that can be set for the drag source and
+ * is transferred to the drop target.
+ * @param dropEvent
+ * Client side drop event.
+ */
+ protected void sendDropEventToServer(String dataTransferText,
+ Event dropEvent) {
+ getRpcProxy(DropTargetRpc.class).drop(dataTransferText);
}
- private void removeTargetIndicator(Element element) {
- element.removeClassName(CLASS_DRAG_OVER);
+ /**
+ * Add class that indicates that the component is a target.
+ *
+ * @param event
+ * The drag enter or dragover event that triggered the indication.
+ */
+ protected void addTargetIndicator(Event event) {
+ getDropTargetElement().addClassName(CLASS_DRAG_OVER);
+ }
+
+ /**
+ * Remove the drag target indicator class name from the target element.
+ * <p>
+ * This is triggered on dragleave, drop and dragover events.
+ *
+ * @param event
+ * the event that triggered the removal of the indicator
+ */
+ protected void removeTargetIndicator(Event event) {
+ getDropTargetElement().removeClassName(CLASS_DRAG_OVER);
}
private native boolean executeScript(NativeEvent event, String script)/*-{
diff --git a/server/src/main/java/com/vaadin/event/dnd/DropTargetExtension.java b/server/src/main/java/com/vaadin/event/dnd/DropTargetExtension.java
index c4a5f981ff..fcca5efadb 100644
--- a/server/src/main/java/com/vaadin/event/dnd/DropTargetExtension.java
+++ b/server/src/main/java/com/vaadin/event/dnd/DropTargetExtension.java
@@ -43,14 +43,25 @@ public class DropTargetExtension<T extends AbstractComponent> extends
* Component to be extended.
*/
public DropTargetExtension(T target) {
+
+ registerDropTargetRpc(target);
+
+ super.extend(target);
+ }
+
+ /**
+ * Register server RPC.
+ *
+ * @param target
+ * Extended component.
+ */
+ protected void registerDropTargetRpc(T target) {
registerRpc((DropTargetRpc) dataTransferText -> {
DropEvent<T> event = new DropEvent<>(target, dataTransferText,
getUI().getActiveDragSource());
fireEvent(event);
});
-
- super.extend(target);
}
/**
diff --git a/server/src/main/java/com/vaadin/event/dnd/grid/GridDropEvent.java b/server/src/main/java/com/vaadin/event/dnd/grid/GridDropEvent.java
new file mode 100644
index 0000000000..96017e3a1d
--- /dev/null
+++ b/server/src/main/java/com/vaadin/event/dnd/grid/GridDropEvent.java
@@ -0,0 +1,67 @@
+/*
+ * 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.event.dnd.grid;
+
+import com.vaadin.event.dnd.DragSourceExtension;
+import com.vaadin.event.dnd.DropEvent;
+import com.vaadin.ui.AbstractComponent;
+import com.vaadin.ui.Grid;
+
+/**
+ * Server side drop event on an HTML5 drop target {@link Grid} row.
+ *
+ * @param <T>
+ * The Grid bean type.
+ * @author Vaadin Ltd.
+ * @see com.vaadin.ui.GridDropTargetExtension#addDropListener(GridDropListener)
+ * @since
+ */
+public class GridDropEvent<T> extends DropEvent<Grid<T>> {
+
+ private final T dropTargetRow;
+
+ /**
+ * Creates a server side Grid row drop event.
+ *
+ * @param target
+ * Grid that received the drop.
+ * @param dataTransferText
+ * Data of type {@code "text"} from the {@code DataTransfer}
+ * object.
+ * @param dragSourceExtension
+ * Drag source extension of the component that initiated the drop
+ * event.
+ * @param dropTargetRowKey
+ * Key of the target row that received the drop.
+ */
+ public GridDropEvent(Grid<T> target, String dataTransferText,
+ DragSourceExtension<? extends AbstractComponent> dragSourceExtension,
+ String dropTargetRowKey) {
+ super(target, dataTransferText, dragSourceExtension);
+
+ dropTargetRow = target.getDataCommunicator().getKeyMapper()
+ .get(dropTargetRowKey);
+ }
+
+ /**
+ * Get the row item source of this event.
+ *
+ * @return The row item this event was originated from.
+ */
+ public T getDropTargetRow() {
+ return dropTargetRow;
+ }
+}
diff --git a/server/src/main/java/com/vaadin/event/dnd/grid/GridDropListener.java b/server/src/main/java/com/vaadin/event/dnd/grid/GridDropListener.java
new file mode 100644
index 0000000000..e1e365fbeb
--- /dev/null
+++ b/server/src/main/java/com/vaadin/event/dnd/grid/GridDropListener.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.event.dnd.grid;
+
+import java.lang.reflect.Method;
+
+import com.vaadin.event.ConnectorEventListener;
+import com.vaadin.event.dnd.DropListener;
+import com.vaadin.event.dnd.DropTargetExtension;
+
+/**
+ * Drop listener for HTML5 drop on a Grid row.
+ *
+ * @param <T>
+ * The Grid bean type.
+ * @author Vaadin Ltd.
+ * @see com.vaadin.ui.GridDropTargetExtension#addDropListener(GridDropListener)
+ * @since
+ */
+@FunctionalInterface
+public interface GridDropListener<T> extends ConnectorEventListener {
+
+ static final Method DROP_METHOD = GridDropListener.class
+ .getDeclaredMethods()[0];
+
+ /**
+ * Called when drop event is fired on a Grid row.
+ *
+ * @param event
+ * Server side drop event.
+ */
+ void drop(GridDropEvent<T> event);
+}
diff --git a/server/src/main/java/com/vaadin/ui/GridDropTargetExtension.java b/server/src/main/java/com/vaadin/ui/GridDropTargetExtension.java
new file mode 100644
index 0000000000..bf75e26783
--- /dev/null
+++ b/server/src/main/java/com/vaadin/ui/GridDropTargetExtension.java
@@ -0,0 +1,72 @@
+/*
+ * 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.ui;
+
+import com.vaadin.event.dnd.DropTargetExtension;
+import com.vaadin.event.dnd.grid.GridDropEvent;
+import com.vaadin.event.dnd.grid.GridDropListener;
+import com.vaadin.shared.Registration;
+import com.vaadin.shared.ui.grid.GridDropTargetExtensionRpc;
+import com.vaadin.shared.ui.grid.GridDropTargetExtensionState;
+
+/**
+ * Makes the rows of a Grid HTML5 drop targets. This is the server side
+ * counterpart of GridDropTargetExtensionConnector.
+ *
+ * @param <T>
+ * Type of the Grid bean.
+ * @author Vaadin Ltd
+ * @since
+ */
+public class GridDropTargetExtension<T> extends DropTargetExtension<Grid<T>> {
+ public GridDropTargetExtension(Grid<T> target) {
+ super(target);
+ }
+
+ @Override
+ protected void registerDropTargetRpc(Grid<T> target) {
+ registerRpc((GridDropTargetExtensionRpc) (dataTransferText, rowKey) -> {
+ GridDropEvent<T> event = new GridDropEvent<>(target,
+ dataTransferText, getUI().getActiveDragSource(), rowKey);
+
+ fireEvent(event);
+ });
+ }
+
+ /**
+ * Attaches drop listener for the current drop target. {@link
+ * GridDropListener#drop(GridDropEvent)} is called when drop event happens
+ * on the client side.
+ *
+ * @param listener
+ * Listener to handle drop event.
+ * @return Handle to be used to remove this listener.
+ */
+ public Registration addDropListener(GridDropListener<T> listener) {
+ return addListener(GridDropEvent.class, listener,
+ GridDropListener.DROP_METHOD);
+ }
+
+ @Override
+ protected GridDropTargetExtensionState getState() {
+ return (GridDropTargetExtensionState) super.getState();
+ }
+
+ @Override
+ protected GridDropTargetExtensionState getState(boolean markAsDirty) {
+ return (GridDropTargetExtensionState) super.getState(markAsDirty);
+ }
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/grid/GridDragSourceExtensionState.java b/shared/src/main/java/com/vaadin/shared/ui/grid/GridDragSourceExtensionState.java
index 39a5917146..682863ab88 100644
--- a/shared/src/main/java/com/vaadin/shared/ui/grid/GridDragSourceExtensionState.java
+++ b/shared/src/main/java/com/vaadin/shared/ui/grid/GridDragSourceExtensionState.java
@@ -26,11 +26,6 @@ import com.vaadin.shared.ui.dnd.DragSourceState;
public class GridDragSourceExtensionState extends DragSourceState {
/**
- * Data type for storing the dragged row's data.
- */
- public static final String DATA_TYPE_DRAG_DATA = "grid-drag-data";
-
- /**
* Json key for storing data for a dragged row.
*/
public static final String JSONKEY_DRAG_DATA = "drag-data";
diff --git a/shared/src/main/java/com/vaadin/shared/ui/grid/GridDropTargetExtensionRpc.java b/shared/src/main/java/com/vaadin/shared/ui/grid/GridDropTargetExtensionRpc.java
new file mode 100644
index 0000000000..ef0dc405b5
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/shared/ui/grid/GridDropTargetExtensionRpc.java
@@ -0,0 +1,39 @@
+/*
+ * 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.shared.ui.grid;
+
+import com.vaadin.shared.communication.ServerRpc;
+
+/**
+ * RPC for firing server side drop event when client side drop event happens on
+ * drop target Grid.
+ *
+ * @author Vaadin Ltd.
+ * @since
+ */
+public interface GridDropTargetExtensionRpc extends ServerRpc {
+
+ /**
+ * Called when drop event happens on client side.
+ *
+ * @param dataTransferText
+ * Data of type {@code "text"} from the {@code DataTransfer}
+ * object.
+ * @param rowKey
+ * Key of the row on which the drop event occured.
+ */
+ public void drop(String dataTransferText, String rowKey);
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/grid/GridDropTargetExtensionState.java b/shared/src/main/java/com/vaadin/shared/ui/grid/GridDropTargetExtensionState.java
new file mode 100644
index 0000000000..c911d529d0
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/shared/ui/grid/GridDropTargetExtensionState.java
@@ -0,0 +1,28 @@
+/*
+ * 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.shared.ui.grid;
+
+import com.vaadin.shared.ui.dnd.DropTargetState;
+
+/**
+ * State class containing parameters for GridDropTargetExtension.
+ *
+ * @author Vaadin Ltd
+ * @since
+ */
+public class GridDropTargetExtensionState extends DropTargetState {
+
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridDragAndDrop.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridDragAndDrop.java
index a6036acac8..0c532e8762 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/grid/GridDragAndDrop.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/grid/GridDragAndDrop.java
@@ -20,28 +20,25 @@ import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
-import com.vaadin.annotations.Widgetset;
-import com.vaadin.event.dnd.DropTargetExtension;
+import com.vaadin.event.dnd.grid.GridDropListener;
+import com.vaadin.server.Page;
import com.vaadin.server.VaadinRequest;
-import com.vaadin.shared.ui.grid.GridDragSourceExtensionState;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Grid;
import com.vaadin.ui.GridDragSourceExtension;
+import com.vaadin.ui.GridDropTargetExtension;
import com.vaadin.ui.HorizontalLayout;
-import com.vaadin.ui.Label;
import com.vaadin.ui.Layout;
import elemental.json.Json;
import elemental.json.JsonObject;
-@Widgetset("com.vaadin.DefaultWidgetSet")
public class GridDragAndDrop extends AbstractTestUIWithLog {
@Override
protected void setup(VaadinRequest request) {
- // Drag source
+ // Drag source Grid
Grid<Bean> dragSourceComponent = new Grid<>();
-
dragSourceComponent.setItems(createItems(50));
dragSourceComponent.addColumn(Bean::getId).setCaption("ID");
dragSourceComponent.addColumn(Bean::getValue).setCaption("Value");
@@ -54,15 +51,20 @@ public class GridDragAndDrop extends AbstractTestUIWithLog {
return ret;
});
- Label dropTargetComponent = new Label("Drop here");
- DropTargetExtension<Label> dropTarget = new DropTargetExtension<>(
- dropTargetComponent);
+ // Drop target Grid
+ Grid<Bean> dropTargetComponent = new Grid<>();
+ dropTargetComponent.setItems(createItems(5));
+ dropTargetComponent.addColumn(Bean::getId).setCaption("ID");
+ dropTargetComponent.addColumn(Bean::getValue).setCaption("Value");
- dropTarget.addDropListener(event -> {
- log(event.getTransferData(
- GridDragSourceExtensionState.DATA_TYPE_DRAG_DATA));
+ GridDropTargetExtension<Bean> dropTarget = new GridDropTargetExtension<>(
+ dropTargetComponent);
+ dropTarget.addDropListener((GridDropListener<Bean>) event -> {
+ log(event.getDataTransferText() + ", targetId=" + event
+ .getDropTargetRow().getId());
});
+ // Layout grids
Layout layout = new HorizontalLayout();
layout.addComponents(dragSourceComponent, dropTargetComponent);
@@ -77,6 +79,9 @@ public class GridDragAndDrop extends AbstractTestUIWithLog {
selectionModeSwitch.setSelectedItem(Grid.SelectionMode.SINGLE);
addComponents(selectionModeSwitch, layout);
+
+ // Set dragover styling
+ Page.getCurrent().getStyles().add(".v-drag-over {color: red;}");
}
private List<Bean> createItems(int num) {
diff --git a/uitest/src/main/java/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java b/uitest/src/main/java/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java
index a2fea1ba15..9895a9ea4f 100644
--- a/uitest/src/main/java/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java
+++ b/uitest/src/main/java/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java
@@ -15,7 +15,9 @@
*/
package com.vaadin.tests.widgetset.client.grid;
+import java.util.List;
import java.util.Map;
+import java.util.function.Consumer;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.TableRowElement;
@@ -126,6 +128,13 @@ public class EscalatorProxy extends Escalator {
public SpacerUpdater getSpacerUpdater() {
return rowContainer.getSpacerUpdater();
}
+
+ @Override
+ public void setNewEscalatorRowCallback(
+ Consumer<List<TableRowElement>> consumer) {
+ throw new UnsupportedOperationException(
+ "NewEscalatorRowCallback function is not supported");
+ }
}
private class RowContainerProxy implements RowContainer {
0035/stable29'>backport/50035/stable29 Nextcloud server, a safe home for all your data: https://github.com/nextcloud/serverwww-data
aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Files/Config/MountProviderCollection.php
blob: 0e08d9d0e83ee9b9a58edef9c0dd24d833204bdf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
<?php
/**
 * @copyright Copyright (c) 2016, ownCloud, Inc.
 *
 * @author Christoph Wurst <christoph@winzerhof-wurst.at>
 * @author Morris Jobke <hey@morrisjobke.de>
 * @author Robin Appelman <robin@icewind.nl>
 * @author Roeland Jago Douma <roeland@famdouma.nl>
 *
 * @license AGPL-3.0
 *
 * This code is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License, version 3,
 * along with this program. If not, see <http://www.gnu.org/licenses/>
 *
 */
namespace OC\Files\Config;

use OC\Hooks\Emitter;
use OC\Hooks\EmitterTrait;
use OCP\Files\Config\IHomeMountProvider;
use OCP\Files\Config\IMountProvider;
use OCP\Files\Config\IMountProviderCollection;
use OCP\Files\Config\IRootMountProvider;
use OCP\Files\Config\IUserMountCache;
use OCP\Files\Mount\IMountManager;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\Storage\IStorageFactory;
use OCP\IUser;

class MountProviderCollection implements IMountProviderCollection, Emitter {
	use EmitterTrait;

	/**
	 * @var \OCP\Files\Config\IHomeMountProvider[]
	 */
	private $homeProviders = [];

	/**
	 * @var \OCP\Files\Config\IMountProvider[]
	 */
	private $providers = [];

	/** @var \OCP\Files\Config\IRootMountProvider[] */
	private $rootProviders = [];

	/**
	 * @var \OCP\Files\Storage\IStorageFactory
	 */
	private $loader;

	/**
	 * @var \OCP\Files\Config\IUserMountCache
	 */
	private $mountCache;

	/** @var callable[] */
	private $mountFilters = [];

	/**
	 * @param \OCP\Files\Storage\IStorageFactory $loader
	 * @param IUserMountCache $mountCache
	 */
	public function __construct(IStorageFactory $loader, IUserMountCache $mountCache) {
		$this->loader = $loader;
		$this->mountCache = $mountCache;
	}

	/**
	 * @param IUser $user
	 * @param IMountProvider[] $providers
	 * @return IMountPoint[]
	 */
	private function getUserMountsForProviders(IUser $user, array $providers): array {
		$loader = $this->loader;
		$mounts = array_map(function (IMountProvider $provider) use ($user, $loader) {
			return $provider->getMountsForUser($user, $loader);
		}, $providers);
		$mounts = array_filter($mounts, function ($result) {
			return is_array($result);
		});
		$mounts = array_reduce($mounts, function (array $mounts, array $providerMounts) {
			return array_merge($mounts, $providerMounts);
		}, []);
		return $this->filterMounts($user, $mounts);
	}

	public function getMountsForUser(IUser $user): array {
		return $this->getUserMountsForProviders($user, $this->providers);
	}

	public function getUserMountsForProviderClasses(IUser $user, array $mountProviderClasses): array {
		$providers = array_filter(
			$this->providers,
			fn (IMountProvider $mountProvider) => (in_array(get_class($mountProvider), $mountProviderClasses))
		);
		return $this->getUserMountsForProviders($user, $providers);
	}

	public function addMountForUser(IUser $user, IMountManager $mountManager, callable $providerFilter = null) {
		// shared mount provider gets to go last since it needs to know existing files
		// to check for name collisions
		$firstMounts = [];
		if ($providerFilter) {
			$providers = array_filter($this->providers, $providerFilter);
		} else {
			$providers = $this->providers;
		}
		$firstProviders = array_filter($providers, function (IMountProvider $provider) {
			return (get_class($provider) !== 'OCA\Files_Sharing\MountProvider');
		});
		$lastProviders = array_filter($providers, function (IMountProvider $provider) {
			return (get_class($provider) === 'OCA\Files_Sharing\MountProvider');
		});
		foreach ($firstProviders as $provider) {
			$mounts = $provider->getMountsForUser($user, $this->loader);
			if (is_array($mounts)) {
				$firstMounts = array_merge($firstMounts, $mounts);
			}
		}
		$firstMounts = $this->filterMounts($user, $firstMounts);
		array_walk($firstMounts, [$mountManager, 'addMount']);

		$lateMounts = [];
		foreach ($lastProviders as $provider) {
			$mounts = $provider->getMountsForUser($user, $this->loader);
			if (is_array($mounts)) {
				$lateMounts = array_merge($lateMounts, $mounts);
			}
		}

		$lateMounts = $this->filterMounts($user, $lateMounts);
		array_walk($lateMounts, [$mountManager, 'addMount']);

		return array_merge($lateMounts, $firstMounts);
	}

	/**
	 * Get the configured home mount for this user
	 *
	 * @param \OCP\IUser $user
	 * @return \OCP\Files\Mount\IMountPoint
	 * @since 9.1.0
	 */
	public function getHomeMountForUser(IUser $user) {
		/** @var \OCP\Files\Config\IHomeMountProvider[] $providers */
		$providers = array_reverse($this->homeProviders); // call the latest registered provider first to give apps an opportunity to overwrite builtin
		foreach ($providers as $homeProvider) {
			if ($mount = $homeProvider->getHomeMountForUser($user, $this->loader)) {
				$mount->setMountPoint('/' . $user->getUID()); //make sure the mountpoint is what we expect
				return $mount;
			}
		}
		throw new \Exception('No home storage configured for user ' . $user);
	}

	/**
	 * Add a provider for mount points
	 *
	 * @param \OCP\Files\Config\IMountProvider $provider
	 */
	public function registerProvider(IMountProvider $provider) {
		$this->providers[] = $provider;

		$this->emit('\OC\Files\Config', 'registerMountProvider', [$provider]);
	}

	public function registerMountFilter(callable $filter) {
		$this->mountFilters[] = $filter;
	}

	private function filterMounts(IUser $user, array $mountPoints) {
		return array_filter($mountPoints, function (IMountPoint $mountPoint) use ($user) {
			foreach ($this->mountFilters as $filter) {
				if ($filter($mountPoint, $user) === false) {
					return false;
				}
			}
			return true;
		});
	}

	/**
	 * Add a provider for home mount points
	 *
	 * @param \OCP\Files\Config\IHomeMountProvider $provider
	 * @since 9.1.0
	 */
	public function registerHomeProvider(IHomeMountProvider $provider) {
		$this->homeProviders[] = $provider;
		$this->emit('\OC\Files\Config', 'registerHomeMountProvider', [$provider]);
	}

	/**
	 * Get the mount cache which can be used to search for mounts without setting up the filesystem
	 *
	 * @return IUserMountCache
	 */
	public function getMountCache() {
		return $this->mountCache;
	}

	public function registerRootProvider(IRootMountProvider $provider) {
		$this->rootProviders[] = $provider;
	}

	/**
	 * Get all root mountpoints
	 *
	 * @return \OCP\Files\Mount\IMountPoint[]
	 * @since 20.0.0
	 */
	public function getRootMounts(): array {
		$loader = $this->loader;
		$mounts = array_map(function (IRootMountProvider $provider) use ($loader) {
			return $provider->getRootMounts($loader);
		}, $this->rootProviders);
		$mounts = array_reduce($mounts, function (array $mounts, array $providerMounts) {
			return array_merge($mounts, $providerMounts);
		}, []);
		return $mounts;
	}

	public function clearProviders() {
		$this->providers = [];
		$this->homeProviders = [];
		$this->rootProviders = [];
	}

	public function getProviders(): array {
		return $this->providers;
	}
}