Merge branch 'master' into packaging
[pithos-web-client] / src / gr / grnet / pithos / web / client / FileUploadDialog.java
1 /*
2  * Copyright 2011-2012 GRNET S.A. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above
9  *      copyright notice, this list of conditions and the following
10  *      disclaimer.
11  *
12  *   2. Redistributions in binary form must reproduce the above
13  *      copyright notice, this list of conditions and the following
14  *      disclaimer in the documentation and/or other materials
15  *      provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  *
30  * The views and conclusions contained in the software and
31  * documentation are those of the authors and should not be
32  * interpreted as representing official policies, either expressed
33  * or implied, of GRNET S.A.
34  */
35 package gr.grnet.pithos.web.client;
36
37 import gr.grnet.pithos.web.client.foldertree.Folder;
38
39 import com.google.gwt.dom.client.NativeEvent;
40 import com.google.gwt.event.dom.client.ClickEvent;
41 import com.google.gwt.event.dom.client.ClickHandler;
42 import com.google.gwt.event.dom.client.KeyCodes;
43 import com.google.gwt.user.client.Command;
44 import com.google.gwt.user.client.Event.NativePreviewEvent;
45 import com.google.gwt.user.client.ui.Anchor;
46 import com.google.gwt.user.client.ui.Button;
47 import com.google.gwt.user.client.ui.DialogBox;
48 import com.google.gwt.user.client.ui.FileUpload;
49 import com.google.gwt.user.client.ui.FlowPanel;
50 import com.google.gwt.user.client.ui.FormPanel;
51 import com.google.gwt.user.client.ui.Grid;
52 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
53 import com.google.gwt.user.client.ui.Hidden;
54 import com.google.gwt.user.client.ui.HorizontalPanel;
55 import com.google.gwt.user.client.ui.Label;
56 import com.google.gwt.user.client.ui.VerticalPanel;
57
58 /**
59  * The 'File upload' dialog box implementation.
60  */
61 public class FileUploadDialog extends DialogBox {
62
63     public static final boolean DONE = true;
64
65         /**
66          * The Form element that performs the file upload.
67          */
68     protected final FormPanel form = new FormPanel();
69
70         private final FileUpload upload = new FileUpload();
71
72         private final Label filenameLabel = new Label();
73
74     private final Label foldernameLabel = new Label();
75
76     private Button submit;
77
78         protected Folder folder;
79
80     protected Pithos app;
81
82         /**
83          * The widget's constructor.
84          */
85         public FileUploadDialog(Pithos _app) {
86                 app = _app;
87                 Anchor close = new Anchor("close");
88                 close.addStyleName("close");
89                 close.addClickHandler(new ClickHandler() {
90                         
91                         @Override
92                         public void onClick(ClickEvent event) {
93                                 close();
94                         }
95                 });
96                 // Set the dialog's caption.
97                 setText("File upload");
98                 setAnimationEnabled(true);
99                 setGlassEnabled(true);
100                 setStyleName("pithos-DialogBox");
101                 setVisible(false);
102                 
103                 // Since we're going to add a FileUpload widget, we'll need to set the
104                 // form to use the POST method, and multipart MIME encoding.
105                 form.setEncoding(FormPanel.ENCODING_MULTIPART);
106                 form.setMethod(FormPanel.METHOD_POST);
107
108                 // Create a panel to hold all of the form widgets.
109                 VerticalPanel panel = new VerticalPanel();
110                 panel.setWidth("470px");
111                 panel.add(close);
112                 form.setWidget(panel);
113
114                 VerticalPanel inner = new VerticalPanel();
115                 inner.addStyleName("inner");
116
117         final Hidden auth = new Hidden("X-Auth-Token");
118         inner.add(auth);
119                 upload.setName("X-Object-Data");
120                 upload.setVisible(false);
121                 filenameLabel.setText("");
122                 filenameLabel.setVisible(false);
123                 filenameLabel.setStyleName("props-labels");
124                 HorizontalPanel fileUploadPanel = new HorizontalPanel();
125                 fileUploadPanel.setVisible(false);
126                 fileUploadPanel.add(filenameLabel);
127                 fileUploadPanel.add(upload);
128                 Grid generalTable = new Grid(2, 2);
129                 generalTable.setText(0, 0, "Folder");
130         generalTable.setWidget(0, 1, foldernameLabel);
131                 generalTable.setWidget(1, 1, fileUploadPanel);
132                 generalTable.getCellFormatter().setStyleName(0, 0, "props-labels");
133         generalTable.getCellFormatter().setStyleName(0, 1, "props-values");
134         generalTable.getCellFormatter().setVisible(1, 0, false);
135                 generalTable.setCellSpacing(4);
136
137                 inner.add(generalTable);
138
139                 FlowPanel uploader = new FlowPanel();
140                 uploader.getElement().setId("uploader");
141                 inner.add(uploader);
142                 
143                 panel.add(inner);
144                 panel.setCellHorizontalAlignment(inner, HasHorizontalAlignment.ALIGN_CENTER);
145                 
146                 setWidget(form);
147         }
148
149         private void refreshFolder() {
150                 if (app.getSelectedTree().equals(app.getFolderTreeView()))
151                         app.updateFolder(folder, true, new Command() {
152                                 
153                                 @Override
154                                 public void execute() {
155                                         app.updateStatistics();
156                                 }
157                         }, true);
158                 else
159                         app.updateOtherSharedFolder(folder, true);
160         }
161         
162         native void setupUpload(FileUploadDialog dlg, String path, String token) /*-{
163                 var uploader = $wnd.$('#uploader').pluploadQueue();
164                 var createUploader = function() {
165                         $wnd.$("#uploader").pluploadQueue({
166                                 // General settings
167                                 runtimes : 'html5, flash, gears, silverlight, browserplus, html4',
168                                 unique_names : true,
169                 
170                                 // Flash settings
171                                 flash_swf_url : 'plupload/js/plupload.flash.swf',
172                 
173                                 // Silverlight settings
174                                 silverlight_xap_url : 'plupload/js/plupload.silverlight.xap',
175                                 
176                                 multiple_queues: true,
177                                 
178                                 preinit: {
179                                         Init: function(up, info) {
180                                                 if ($wnd.console && $wnd.console.log)
181                                                         $wnd.console.log("Init fired");
182                                                 up.settings.file_data_name = "X-Object-Data";                           
183                                         }
184                                         
185                                 },
186                                 
187                                 init: {
188                                         FilesAdded: function(up, files) {
189                                                 for (var j=0; j<files.length; j++)
190                                                         files[j].url = up.path + "/" + files[j].name + "?X-Auth-Token=" + encodeURIComponent(token);
191                                         },
192                                         
193                                         BeforeUpload: function(up, file) {
194                                                 if ($wnd.console && $wnd.console.log)
195                                                         $wnd.console.log('About to upload ' + file.url);
196                                                 up.settings.url = file.url;
197                                         },
198                                         
199                                         FileUploaded: function(up, file, response) {
200                                                 if ($wnd.console && $wnd.console.log) {
201                                                         $wnd.console.log('File ' + file.name + ' uploaded');
202                                                         $wnd.console.log('Response: ' + response);
203                                                 }
204                                         },
205                                         
206                                         UploadComplete: function(up, files) {
207                                                 if ($wnd.console && $wnd.console.log)
208                                                         $wnd.console.log('All files finished');
209                                                 dlg.@gr.grnet.pithos.web.client.FileUploadDialog::hideUploadIndicator()();
210                                                 dlg.@gr.grnet.pithos.web.client.FileUploadDialog::refreshFolder()();
211                                         },
212                                         
213                                         Error: function(up, error) {
214                                                 if ($wnd.console && $wnd.console.log)
215                                                         $wnd.console.log("Error occured:" + error);
216                                         }
217                                 }
218                         });
219                         return $wnd.$('#uploader').pluploadQueue();
220                 };
221                 
222                 if ($wnd.console && $wnd.console.log)
223                         $wnd.console.log(uploader);
224                 if (!uploader) {
225                         uploader = createUploader();
226                 }
227                 else {
228                         var removeAll = true;
229                         var files = uploader.files;
230                         if ($wnd.console && $wnd.console.log)
231                                 $wnd.console.log('About to check ' + files.length + ' files');
232                         for (var i=0; i<files.length; i++) {
233                                 var f = files[i];
234                                 if (f.status != $wnd.plupload.DONE && f.status != $wnd.plupload.FAILED) {
235                                         removeAll = false;
236                                         break;
237                                 }
238                         }
239                         if (removeAll) {
240                                 if ($wnd.console && $wnd.console.log)
241                                         $wnd.console.log('About to remove ' + files.length + ' files');
242                                 uploader.destroy();
243                                 uploader = createUploader();
244                                 if ($wnd.console && $wnd.console.log)
245                                         $wnd.console.log(uploader);
246                         }
247                 }
248                 uploader.path = path;
249         }-*/;
250         
251         native boolean isUploading()/*-{
252                 var uploader = $wnd.$("#uploader").pluploadQueue();
253                 var files = uploader.files;
254                 for (var i=0; i<files.length; i++) {
255                         var f = files[i];
256                         if (f.status == $wnd.plupload.UPLOADING) {
257                                 return true;
258                         }
259                 }
260                 return false;
261         }-*/;
262         
263         @Override
264         protected void onPreviewNativeEvent(NativePreviewEvent event) {
265                 super.onPreviewNativeEvent(event);
266
267                 NativeEvent evt = event.getNativeEvent();
268                 if (evt.getType().equals("keydown"))
269                         // Use the popup's key preview hooks to close the dialog when
270                         // escape is pressed.
271                         switch (evt.getKeyCode()) {
272                                 case KeyCodes.KEY_ESCAPE:
273                                         close();
274                                         break;
275                         }
276         }
277
278         public void setFolder(Folder folder) {
279                 this.folder = folder;
280                 foldernameLabel.setText(folder.getName());
281         }
282
283         @Override
284         public void center() {
285                 app.hideUploadIndicator();
286                 setVisible(true);
287                 setModal(true);
288                 super.center();
289                 String path = app.getApiPath() + folder.getOwner() + folder.getUri();
290                 setupUpload(this, path, app.getToken());
291                 super.center();
292         }
293         
294         private void hideUploadIndicator() {
295                 app.hideUploadIndicator();
296         }
297         
298         void close() {
299                 setVisible(false);
300                 setModal(false);
301                 if (isUploading())
302                         app.showUploadIndicator();
303         }
304 }