Package com.vaadin.ui

Source Code of com.vaadin.ui.DragAndDropWrapper$WrapperTransferable

/*
* Copyright 2010 IT Mill 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 java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
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 {

            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);
        }

    }
}
TOP

Related Classes of com.vaadin.ui.DragAndDropWrapper$WrapperTransferable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.