123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- /*
- @ITMillApache2LicenseForJavaFiles@
- */
- package com.vaadin.ui;
-
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.io.Serializable;
- import java.util.HashMap;
- import java.util.Map;
-
- import com.vaadin.event.Transferable;
- import com.vaadin.event.TransferableImpl;
- import com.vaadin.event.dd.DragSource;
- import com.vaadin.event.dd.DropHandler;
- import com.vaadin.event.dd.DropTarget;
- import com.vaadin.event.dd.TargetDetails;
- import com.vaadin.event.dd.TargetDetailsImpl;
- import com.vaadin.terminal.PaintException;
- import com.vaadin.terminal.PaintTarget;
- import com.vaadin.terminal.UploadStream;
- import com.vaadin.terminal.gwt.client.MouseEventDetails;
- import com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper;
- import com.vaadin.terminal.gwt.client.ui.dd.HorizontalDropLocation;
- import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
- import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
- import com.vaadin.ui.DragAndDropWrapper.WrapperTransferable.Html5File;
- import com.vaadin.ui.Upload.Receiver;
- import com.vaadin.ui.Upload.UploadException;
-
- @SuppressWarnings("serial")
- @ClientWidget(VDragAndDropWrapper.class)
- public class DragAndDropWrapper extends CustomComponent implements DropTarget,
- DragSource {
-
- public class WrapperTransferable extends TransferableImpl {
-
- private Html5File[] files;
-
- public WrapperTransferable(Component sourceComponent,
- Map<String, Object> rawVariables) {
- super(sourceComponent, rawVariables);
- Integer fc = (Integer) rawVariables.get("filecount");
- if (fc != null) {
- files = new Html5File[fc];
- for (int i = 0; i < fc; i++) {
- Html5File file = new Html5File();
- String id = (String) rawVariables.get("fi" + i);
- file.name = (String) rawVariables.get("fn" + i);
- file.size = (Integer) rawVariables.get("fs" + i);
- file.type = (String) rawVariables.get("ft" + i);
- files[i] = file;
- receivers.put(id, file);
- }
- }
- }
-
- /**
- * The component in wrapper that is being dragged or null if the
- * transferrable is not a component (most likely an html5 drag).
- *
- * @return
- */
- public Component getDraggedComponent() {
- Component object = (Component) getData("component");
- return object;
- }
-
- /**
- * @return the mouse down event that started the drag and drop operation
- */
- public MouseEventDetails getMouseDownEvent() {
- return MouseEventDetails.deSerialize((String) getData("mouseDown"));
- }
-
- public Html5File[] getFiles() {
- return files;
- }
-
- public String getText() {
- String data = (String) getData("Text"); // IE, html5
- if (data == null) {
- // check for "text/plain" (webkit)
- data = (String) getData("text/plain");
- }
- return data;
- }
-
- public String getHtml() {
- String data = (String) getData("Html"); // IE, html5
- if (data == null) {
- // check for "text/plain" (webkit)
- data = (String) getData("text/html");
- }
- return data;
- }
-
- /**
- * {@link DragAndDropWrapper} can receive also files from client
- * computer if appropriate HTML 5 features are supported on client side.
- * This class wraps information about dragged file on server side.
- */
- public class Html5File implements Serializable {
-
- public String name;
- private int size;
- private Receiver receiver;
- private String type;
-
- public String getFileName() {
- return name;
- }
-
- public int getFileSize() {
- return size;
- }
-
- public String getType() {
- return type;
- }
-
- /**
- * Sets the {@link Receiver} that into which the file contents will
- * be written. Usage of Reveiver is similar to {@link Upload}
- * component.
- *
- * <p>
- * <em>Note!</em> receiving file contents is experimental feature
- * depending on HTML 5 API's. It is supported only by Firefox 3.6 at
- * this time.
- *
- * @param receiver
- * the callback that returns stream where the
- * implementation writes the file contents as it arrives.
- */
- public void setReceiver(Receiver receiver) {
- this.receiver = receiver;
- }
-
- }
-
- }
-
- private Map<String, Html5File> receivers = new HashMap<String, Html5File>();
-
- public class WrapperTargetDetails extends TargetDetailsImpl {
-
- public WrapperTargetDetails(Map<String, Object> rawDropData) {
- super(rawDropData, DragAndDropWrapper.this);
- }
-
- /**
- * @return the absolute position of wrapper on the page
- */
- public Integer getAbsoluteLeft() {
- return (Integer) getData("absoluteLeft");
- }
-
- /**
- *
- * @return the absolute position of wrapper on the page
- */
- public Integer getAbsoluteTop() {
- return (Integer) getData("absoluteTop");
- }
-
- /**
- * @return details about the actual event that caused the event details.
- * Practically mouse move or mouse up.
- */
- public MouseEventDetails getMouseEvent() {
- return MouseEventDetails
- .deSerialize((String) getData("mouseEvent"));
- }
-
- public VerticalDropLocation verticalDropLocation() {
- return VerticalDropLocation
- .valueOf((String) getData("verticalLocation"));
- }
-
- public HorizontalDropLocation horizontalDropLocation() {
- return HorizontalDropLocation
- .valueOf((String) getData("horizontalLocation"));
- }
-
- }
-
- public enum DragStartMode {
- /**
- * {@link DragAndDropWrapper} does not start drag events at all
- */
- NONE,
- /**
- * The component on which the drag started will be shown as drag image.
- */
- COMPONENT,
- /**
- * The whole wrapper is used as a drag image when dragging.
- */
- WRAPPER
- }
-
- private DragStartMode dragStartMode = DragStartMode.NONE;
-
- /**
- * Wraps given component in a {@link DragAndDropWrapper}.
- *
- * @param root
- * the component to be wrapped
- */
- public DragAndDropWrapper(Component root) {
- super(root);
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- super.paintContent(target);
- target.addAttribute("dragStartMode", dragStartMode.ordinal());
- if (getDropHandler() != null) {
- getDropHandler().getAcceptCriterion().paint(target);
- }
- }
-
- private DropHandler dropHandler;
-
- public DropHandler getDropHandler() {
- return dropHandler;
- }
-
- public void setDropHandler(DropHandler dropHandler) {
- this.dropHandler = dropHandler;
- requestRepaint();
- }
-
- public TargetDetails translateDropTargetDetails(
- Map<String, Object> clientVariables) {
- return new WrapperTargetDetails(clientVariables);
- }
-
- public Transferable getTransferable(final Map<String, Object> rawVariables) {
- return new WrapperTransferable(this, rawVariables);
- }
-
- public void setDragStartMode(DragStartMode dragStartMode) {
- this.dragStartMode = dragStartMode;
- requestRepaint();
- }
-
- public DragStartMode getDragStartMode() {
- return dragStartMode;
- }
-
- /**
- * This method should only be used by Vaadin terminal implementation. This
- * is not end user api.
- *
- * TODO should fire progress events + end/succes events like upload. Not
- * critical until we have a wider browser support for HTML5 File API
- *
- * @param upstream
- * @param fileId
- * @throws UploadException
- */
- public void receiveFile(UploadStream upstream, String fileId)
- throws UploadException {
- Html5File file = receivers.get(fileId);
- if (file != null && file.receiver != null) {
- OutputStream receiveUpload = file.receiver.receiveUpload(
- file.getFileName(), "TODO");
-
- InputStream stream = upstream.getStream();
- byte[] buf = new byte[AbstractApplicationServlet.MAX_BUFFER_SIZE];
- int bytesRead;
- try {
- while ((bytesRead = stream.read(buf)) != -1) {
- receiveUpload.write(buf, 0, bytesRead);
- }
- receiveUpload.close();
- } catch (IOException e) {
- throw new UploadException(e);
- }
- // clean up the reference when file is downloaded
- receivers.remove(fileId);
- }
-
- }
- }
|