View Javadoc

1   /**********************************************
2    * Copyright (C) 2011 Lukas laag
3    * This file is part of lib-gwt-file.
4    * 
5    * lib-gwt-file is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU Lesser General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    * 
10   * lib-gwt-file is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU Lesser General Public License for more details.
14   * 
15   * You should have received a copy of the GNU Lesser General Public License
16   * along with lib-gwt-file.  If not, see http://www.gnu.org/licenses/
17   **********************************************/
18  package org.vectomatic.file;
19  
20  import org.vectomatic.file.impl.FileListImpl;
21  
22  import com.google.gwt.dom.client.Document;
23  import com.google.gwt.dom.client.Element;
24  import com.google.gwt.dom.client.FormElement;
25  import com.google.gwt.dom.client.InputElement;
26  import com.google.gwt.event.dom.client.ChangeEvent;
27  import com.google.gwt.event.dom.client.ChangeHandler;
28  import com.google.gwt.event.dom.client.HasChangeHandlers;
29  import com.google.gwt.event.shared.HandlerRegistration;
30  import com.google.gwt.user.client.Event;
31  import com.google.gwt.user.client.ui.HasEnabled;
32  import com.google.gwt.user.client.ui.HasName;
33  import com.google.gwt.user.client.ui.RootPanel;
34  import com.google.gwt.user.client.ui.Widget;
35  
36  /**
37   * FileUpload widget with support for multiple files.
38   * @author laaglu
39   */
40  public class FileUploadExt extends Widget implements HasName, HasChangeHandlers, HasEnabled {
41  	/**
42  	 * Constructor. This constructors creates instances
43  	 * with multiple file support activated by default.
44  	 */
45  	public FileUploadExt() {
46  		this(true);
47  	}
48  	/**
49  	 * Constructor.
50  	 * @param multiple true to active multiple file upload support, false otherwise 
51  	 */
52  	public FileUploadExt(boolean multiple) {
53  		this(Document.get().createFileInputElement(), multiple);
54  	}
55  	
56  	protected FileUploadExt(Element element, boolean multiple) {
57  	    setElement(element);
58  	    setStyleName("gwt-FileUpload");
59  		setMultiple(multiple);
60  	}
61  	
62  	/**
63  	 * Returns true if support for multiple file upload is activated, false otherwise.
64  	 * @return true if support for multiple file upload is activated
65  	 */
66  	public boolean isMultiple() {
67  		return isMultiple(getElement());
68  	}
69  	private static final native boolean isMultiple(Element element) /*-{
70  	  return element.multiple;
71  	}-*/;
72  	
73  	/**
74  	 * Sets support for multiple file upload.
75  	 * @param value true to activate support for multiple file upload, false otherwise.
76  	 */
77  	public void setMultiple(boolean value) {
78  		setMultiple(getElement(), value);
79  	} 
80  	private static final native void setMultiple(Element element, boolean value) /*-{
81  	  element.multiple = value;
82  	}-*/; 
83  	/**
84  	 * Returns the files selected by the end-user.
85  	 * @return the files selected by the end-user.
86  	 */
87  	public FileList getFiles() {
88  		return new FileList(getFiles(getElement()));
89  	}
90  	private static final native FileListImpl getFiles(Element element) /*-{
91  	  return element.files;
92  	}-*/;
93  	/**
94  	 * Shows the file selection box.
95  	 */
96  	public void click() {
97  		click(getElement());
98  	}
99  	private static final native void click(Element element) /*-{
100 	  element.click();
101 	}-*/; 
102 	
103 	@Override
104 	public void onBrowserEvent(Event event) {
105 		// Fix webkit bug
106 		// input file will not fire change event if one chooses the same file twice in a row
107 		super.onBrowserEvent(event);
108 		Element parent = getElement().getParentElement();
109 		Element nextSibling = getElement().getNextSiblingElement();
110 		FormElement form = Document.get().createFormElement();
111 		form.appendChild(getElement());
112 		form.reset();
113 		parent.insertBefore(getElement(), nextSibling);
114 	}
115 	
116 	//====================================================
117 	//
118 	//            Copied from GWT's FileUpload
119 	//
120 	//====================================================
121 	
122 	/**
123 	 * Creates a FileUploadExt widget that wraps an existing <input
124 	 * type='file'> element.
125 	 * 
126 	 * This element must already be attached to the document. If the element is
127 	 * removed from the document, you must call
128 	 * {@link RootPanel#detachNow(Widget)}.
129 	 * 
130 	 * @param element the element to be wrapped
131 	 * @param multiple true to active multiple file upload support, false otherwise 
132 	 */
133 	public static FileUploadExt wrap(Element element, boolean multiple) {
134 		// Assert that the element is attached.
135 		assert Document.get().getBody().isOrHasChild(element);
136 
137 		FileUploadExt fileUpload = new FileUploadExt(element, multiple);
138 
139 		// Mark it attached and remember it for cleanup.
140 		fileUpload.onAttach();
141 		RootPanel.detachOnWindowClose(fileUpload);
142 
143 		return fileUpload;
144 	}
145 	
146 	public HandlerRegistration addChangeHandler(ChangeHandler handler) {
147 		return addDomHandler(handler, ChangeEvent.getType());
148 	}
149 
150 	/**
151 	 * Gets the filename selected by the user. This property has no mutator, as
152 	 * browser security restrictions preclude setting it.
153 	 * 
154 	 * @return the widget's filename
155 	 */
156 	public String getFilename() {
157 		return getInputElement().getValue();
158 	}
159 
160 	public String getName() {
161 		return getInputElement().getName();
162 	}
163 
164 	/**
165 	 * Gets whether this widget is enabled.
166 	 * 
167 	 * @return <code>true</code> if the widget is enabled
168 	 */
169 	public boolean isEnabled() {
170 		return !getElement().getPropertyBoolean("disabled");
171 	}	
172 	/**
173 	 * Sets whether this widget is enabled.
174 	 * 
175 	 * @param enabled
176 	 *            <code>true</code> to enable the widget, <code>false</code> to
177 	 *            disable it
178 	 */
179 	public void setEnabled(boolean enabled) {
180 		getElement().setPropertyBoolean("disabled", !enabled);
181 	}
182 
183 	public void setName(String name) {
184 		getInputElement().setName(name);
185 	}
186 
187 	private InputElement getInputElement() {
188 		return getElement().cast();
189 	}
190 }