diff options
author | Artur Signell <artur@vaadin.com> | 2014-02-03 21:46:06 +0200 |
---|---|---|
committer | Artur Signell <artur@vaadin.com> | 2014-02-21 12:19:41 +0200 |
commit | 09969ce1fedb3dc9cca863c393735f64bfbbedc1 (patch) | |
tree | 381fd4f2d1b5f0cf2db4b82d97b8017547ec1e7f | |
parent | de70ee2f0132661c9bf771cb66a40d1961073037 (diff) | |
download | vaadin-framework-09969ce1fedb3dc9cca863c393735f64bfbbedc1.tar.gz vaadin-framework-09969ce1fedb3dc9cca863c393735f64bfbbedc1.zip |
Add change event for Upload (#13222)
Change-Id: I9850888b1997104cbc493ae0882316a9d2b1cedd
5 files changed, 270 insertions, 1 deletions
diff --git a/client/src/com/vaadin/client/ui/upload/UploadConnector.java b/client/src/com/vaadin/client/ui/upload/UploadConnector.java index 989a913adc..03f1a2802c 100644 --- a/client/src/com/vaadin/client/ui/upload/UploadConnector.java +++ b/client/src/com/vaadin/client/ui/upload/UploadConnector.java @@ -16,13 +16,17 @@ package com.vaadin.client.ui.upload; +import com.google.gwt.event.dom.client.ChangeEvent; +import com.google.gwt.event.dom.client.ChangeHandler; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.Paintable; import com.vaadin.client.UIDL; import com.vaadin.client.ui.AbstractComponentConnector; import com.vaadin.client.ui.VUpload; +import com.vaadin.shared.EventId; import com.vaadin.shared.ui.Connect; import com.vaadin.shared.ui.upload.UploadClientRpc; +import com.vaadin.shared.ui.upload.UploadServerRpc; import com.vaadin.ui.Upload; @Connect(Upload.class) @@ -39,6 +43,21 @@ public class UploadConnector extends AbstractComponentConnector implements } @Override + protected void init() { + super.init(); + + getWidget().fu.addChangeHandler(new ChangeHandler() { + @Override + public void onChange(ChangeEvent event) { + if (hasEventListener(EventId.CHANGE)) { + getRpcProxy(UploadServerRpc.class).change( + getWidget().fu.getFilename()); + } + } + }); + } + + @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { if (!isRealUpdate(uidl)) { return; diff --git a/server/src/com/vaadin/ui/Upload.java b/server/src/com/vaadin/ui/Upload.java index 98f5d2ded9..c8d9f3ff09 100644 --- a/server/src/com/vaadin/ui/Upload.java +++ b/server/src/com/vaadin/ui/Upload.java @@ -28,7 +28,10 @@ import com.vaadin.server.NoOutputStreamException; import com.vaadin.server.PaintException; import com.vaadin.server.PaintTarget; import com.vaadin.server.StreamVariable.StreamingProgressEvent; +import com.vaadin.shared.EventId; import com.vaadin.shared.ui.upload.UploadClientRpc; +import com.vaadin.shared.ui.upload.UploadServerRpc; +import com.vaadin.util.ReflectTools; /** * Component for uploading files from client to server. @@ -113,9 +116,16 @@ public class Upload extends AbstractComponent implements Component.Focusable, * The receiver must be set before performing an upload. */ public Upload() { + registerRpc(new UploadServerRpc() { + @Override + public void change(String filename) { + fireEvent(new ChangeEvent(Upload.this, filename)); + } + }); } public Upload(String caption, Receiver uploadReceiver) { + this(); setCaption(caption); receiver = uploadReceiver; } @@ -486,6 +496,42 @@ public class Upload extends AbstractComponent implements Component.Focusable, } /** + * Upload.ChangeEvent event is sent when the value (filename) of the upload + * changes. + * + * @since 7.2 + */ + public static class ChangeEvent extends Component.Event { + + private final String filename; + + public ChangeEvent(Upload source, String filename) { + super(source); + this.filename = filename; + } + + /** + * Uploads where the event occurred. + * + * @return the Source of the event. + */ + @Override + public Upload getSource() { + return (Upload) super.getSource(); + } + + /** + * Gets the file name. + * + * @return the filename. + */ + public String getFilename() { + return filename; + } + + } + + /** * Receives the events when the upload starts. * * @author Vaadin Ltd. @@ -554,6 +600,25 @@ public class Upload extends AbstractComponent implements Component.Focusable, } /** + * Listener for {@link ChangeEvent} + * + * @since 7.2 + */ + public interface ChangeListener extends Serializable { + + Method FILENAME_CHANGED = ReflectTools.findMethod(ChangeListener.class, + "filenameChanged", ChangeEvent.class); + + /** + * A file has been selected but upload has not yet started. + * + * @param event + * the change event + */ + public void filenameChanged(ChangeEvent event); + } + + /** * Adds the upload started event listener. * * @param listener @@ -740,6 +805,27 @@ public class Upload extends AbstractComponent implements Component.Focusable, } /** + * Adds a filename change event listener + * + * @param listener + * the Listener to add + */ + public void addChangeListener(ChangeListener listener) { + super.addListener(EventId.CHANGE, ChangeEvent.class, listener, + ChangeListener.FILENAME_CHANGED); + } + + /** + * Removes a filename change event listener + * + * @param listener + * the listener to be removed + */ + public void removeChangeListener(ChangeListener listener) { + super.removeListener(EventId.CHANGE, ChangeEvent.class, listener); + } + + /** * @deprecated As of 7.0, replaced by * {@link #removeProgressListener(ProgressListener)} **/ @@ -1040,7 +1126,11 @@ public class Upload extends AbstractComponent implements Component.Focusable, @Override public OutputStream getOutputStream() { - OutputStream receiveUpload = receiver.receiveUpload( + if (getReceiver() == null) { + throw new IllegalStateException( + "Upload cannot be performed without a receiver set"); + } + OutputStream receiveUpload = getReceiver().receiveUpload( lastStartedEvent.getFileName(), lastStartedEvent.getMimeType()); lastStartedEvent = null; diff --git a/shared/src/com/vaadin/shared/EventId.java b/shared/src/com/vaadin/shared/EventId.java index d669f8fa83..7cf760b885 100644 --- a/shared/src/com/vaadin/shared/EventId.java +++ b/shared/src/com/vaadin/shared/EventId.java @@ -23,4 +23,6 @@ public interface EventId extends Serializable { public static final String CLICK_EVENT_IDENTIFIER = "click"; public static final String LAYOUT_CLICK_EVENT_IDENTIFIER = "lClick"; public static final String POLL = "poll"; + public static final String CHANGE = "change"; + } diff --git a/shared/src/com/vaadin/shared/ui/upload/UploadServerRpc.java b/shared/src/com/vaadin/shared/ui/upload/UploadServerRpc.java new file mode 100644 index 0000000000..79a6778da3 --- /dev/null +++ b/shared/src/com/vaadin/shared/ui/upload/UploadServerRpc.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2013 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.upload; + +import com.vaadin.shared.communication.ServerRpc; + +public interface UploadServerRpc extends ServerRpc { + + /** + * Event sent when the file name of the upload component is changed. + * + * @param filename + * The filename + */ + void change(String filename); + +} diff --git a/uitest/src/com/vaadin/tests/components/ui/MultiFileUploadTest.java b/uitest/src/com/vaadin/tests/components/ui/MultiFileUploadTest.java new file mode 100644 index 0000000000..8f3e08335f --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/MultiFileUploadTest.java @@ -0,0 +1,128 @@ +/* + * Copyright 2000-2013 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.tests.components.ui; + +import java.io.IOException; +import java.io.OutputStream; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Upload; +import com.vaadin.ui.Upload.ChangeEvent; +import com.vaadin.ui.Upload.ChangeListener; +import com.vaadin.ui.Upload.FailedEvent; +import com.vaadin.ui.Upload.FailedListener; +import com.vaadin.ui.Upload.Receiver; +import com.vaadin.ui.Upload.SucceededEvent; +import com.vaadin.ui.Upload.SucceededListener; +import com.vaadin.ui.VerticalLayout; + +public class MultiFileUploadTest extends AbstractTestUIWithLog { + + private ChangeListener changeListener = new ChangeListener() { + + @Override + public void filenameChanged(ChangeEvent event) { + if (event.getFilename().equals("")) { + removeUpload(event.getSource()); + } else { + addUpload(); + } + + } + }; + private VerticalLayout uploadsLayout = new VerticalLayout(); + + @Override + protected void setup(VaadinRequest request) { + getPage().getStyles().add( + ".v-upload-hidden-button .v-button {display:none};"); + addUpload(); + addComponent(uploadsLayout); + addComponent(new Button("Upload files", new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + for (Upload u : getUploads()) { + u.submitUpload(); + } + } + })); + } + + protected Iterable<Upload> getUploads() { + return (Iterable) uploadsLayout; + } + + protected void removeUpload(Upload source) { + uploadsLayout.removeComponent(source); + + } + + protected void addUpload() { + Upload upload = createUpload(); + upload.addSucceededListener(new SucceededListener() { + + @Override + public void uploadSucceeded(SucceededEvent event) { + log("Upload of " + event.getFilename() + " complete"); + uploadsLayout.removeComponent(event.getUpload()); + } + }); + + upload.addFailedListener(new FailedListener() { + @Override + public void uploadFailed(FailedEvent event) { + log("Upload of " + event.getFilename() + " FAILED"); + } + }); + + upload.setReceiver(new Receiver() { + @Override + public OutputStream receiveUpload(String filename, String mimeType) { + return new OutputStream() { + @Override + public void write(int arg0) throws IOException { + + } + }; + } + }); + upload.setStyleName("hidden-button"); + uploadsLayout.addComponent(upload); + + } + + private Upload createUpload() { + Upload upload = new Upload(); + upload.addChangeListener(changeListener); + return upload; + } + + @Override + protected String getTestDescription() { + return "Tests that an Upload change event can be used to create a multiple file upload component"; + } + + @Override + protected Integer getTicketNumber() { + return 13222; + } + +} |