001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.ui.client;
029
030import org.opencms.ade.upload.client.I_CmsUploadContext;
031import org.opencms.ade.upload.client.ui.CmsDialogUploadButtonHandler;
032import org.opencms.gwt.client.ui.input.upload.CmsFileInfo;
033import org.opencms.ui.components.extensions.CmsUploadAreaExtension;
034import org.opencms.ui.shared.components.CmsUploadAreaState;
035import org.opencms.ui.shared.rpc.I_CmsUploadRpc;
036
037import java.util.ArrayList;
038import java.util.List;
039
040import com.google.common.base.Supplier;
041import com.google.gwt.core.client.JavaScriptObject;
042import com.google.gwt.core.client.JsArray;
043import com.google.gwt.user.client.ui.Widget;
044import com.vaadin.client.ComponentConnector;
045import com.vaadin.client.ServerConnector;
046import com.vaadin.client.extensions.AbstractExtensionConnector;
047import com.vaadin.shared.ui.Connect;
048
049/**
050 * The upload area connector.<p>
051 */
052@Connect(CmsUploadAreaExtension.class)
053public class CmsUploadAreaConnector extends AbstractExtensionConnector {
054
055    /** The serial version id. */
056    private static final long serialVersionUID = 190108090241764065L;
057
058    /** The RPC proxy. */
059    private I_CmsUploadRpc m_rpc;
060
061    /** The widget to enhance. */
062    private Widget m_widget;
063
064    /**
065     * Constructor.<p>
066     */
067    public CmsUploadAreaConnector() {
068
069        m_rpc = getRpcProxy(I_CmsUploadRpc.class);
070    }
071
072    /**
073     * @see com.vaadin.client.ui.AbstractConnector#getState()
074     */
075    @Override
076    public CmsUploadAreaState getState() {
077
078        return (CmsUploadAreaState)super.getState();
079    }
080
081    /**
082     * @see com.vaadin.client.extensions.AbstractExtensionConnector#extend(com.vaadin.client.ServerConnector)
083     */
084    @Override
085    protected void extend(ServerConnector target) {
086
087        // Get the extended widget
088        m_widget = ((ComponentConnector)target).getWidget();
089        initUploadZone(m_widget.getElement());
090    }
091
092    /**
093     * Called on drag out.<p>
094     */
095    void dragOut() {
096
097        m_widget.removeStyleName("o-upload-drop");
098    }
099
100    /**
101     * Called on drag over.<p>
102     */
103    void dragOver() {
104
105        m_widget.addStyleName("o-upload-drop");
106    }
107
108    /**
109     * Called once the upload is finished<p>
110     *
111     * @param files the uploaded files
112     */
113    void uploadFinished(List<String> files) {
114
115        m_rpc.onUploadFinished(files);
116    }
117
118    /**
119     * Initializes the upload drop zone event handlers.<p>
120     *
121     * @param element the drop zone element
122     */
123    private native void initUploadZone(JavaScriptObject element)/*-{
124        // check for file api support
125        if ((typeof FileReader == 'function' || typeof FileReader == 'object')
126                && (typeof FormData == 'function' || typeof FormData == 'object')) {
127            var self = this;
128
129            function isFileDrag(event) {
130                var result = true;
131                var dt = event.dataTransfer;
132                for (var i = 0; i < dt.types.length; i++) {
133                    // in case the types list contains text/html, we assume a DOM element is dragged, and no files
134                    if (dt.types[i] == "text/html") {
135                        result = false;
136                        break;
137                    }
138                }
139                return result;
140            }
141
142            function dragover(event) {
143                if (isFileDrag(event)) {
144                    event.stopPropagation();
145                    event.preventDefault();
146                    self.@org.opencms.ui.client.CmsUploadAreaConnector::dragOver()();
147                }
148            }
149
150            function dragleave(event) {
151                if (isFileDrag(event)) {
152                    event.stopPropagation();
153                    event.preventDefault();
154                    self.@org.opencms.ui.client.CmsUploadAreaConnector::dragOut()();
155                }
156            }
157
158            function drop(event) {
159                if (isFileDrag(event)) {
160                    event.stopPropagation();
161                    event.preventDefault();
162                    self.@org.opencms.ui.client.CmsUploadAreaConnector::dragOut()();
163                    var dt = event.dataTransfer;
164                    var files = dt.files;
165                    self.@org.opencms.ui.client.CmsUploadAreaConnector::openUploadWithFiles(Lcom/google/gwt/core/client/JavaScriptObject;)(files);
166                }
167            }
168
169            element.addEventListener("dragover", dragover, false);
170            element.addEventListener("dragexit", dragleave, false);
171            element.addEventListener("dragleave", dragleave, false);
172            element.addEventListener("dragend", dragleave, false);
173            element.addEventListener("drop", drop, false);
174        }
175    }-*/;
176
177    /**
178     * Opens the upload dialog with the given file references to upload.<p>
179     *
180     * @param files the file references
181     */
182    private void openUploadWithFiles(JavaScriptObject files) {
183
184        if (getState().getTargetFolderRootPath() == null) {
185            return;
186        }
187        JsArray<CmsFileInfo> cmsFiles = files.cast();
188        List<CmsFileInfo> fileObjects = new ArrayList<CmsFileInfo>();
189        for (int i = 0; i < cmsFiles.length(); ++i) {
190            fileObjects.add(cmsFiles.get(i));
191        }
192        CmsDialogUploadButtonHandler buttonHandler = new CmsDialogUploadButtonHandler(
193            new Supplier<I_CmsUploadContext>() {
194
195                /**
196                 * @see com.google.common.base.Supplier#get()
197                 */
198                public I_CmsUploadContext get() {
199
200                    return new I_CmsUploadContext() {
201
202                        public void onUploadFinished(List<String> uploadedFiles) {
203
204                            uploadFinished(uploadedFiles);
205                        }
206
207                    };
208                }
209            });
210        buttonHandler.setIsTargetRootPath(true);
211        buttonHandler.setTargetFolder(getState().getTargetFolderRootPath());
212        buttonHandler.openDialogWithFiles(fileObjects);
213    }
214}