CSS changes
[pithos-web-client] / src / gr / grnet / pithos / web / client / FileUploadDialog.java
1 /*
2  * Copyright 2011 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.File;
38 import gr.grnet.pithos.web.client.foldertree.Folder;
39
40 import com.google.gwt.core.client.GWT;
41 import com.google.gwt.dom.client.NativeEvent;
42 import com.google.gwt.event.dom.client.ClickEvent;
43 import com.google.gwt.event.dom.client.ClickHandler;
44 import com.google.gwt.event.dom.client.KeyCodes;
45 import com.google.gwt.user.client.Event.NativePreviewEvent;
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.FormPanel;
50 import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
51 import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteHandler;
52 import com.google.gwt.user.client.ui.FormPanel.SubmitEvent;
53 import com.google.gwt.user.client.ui.FormPanel.SubmitHandler;
54 import com.google.gwt.user.client.ui.Grid;
55 import com.google.gwt.user.client.ui.HTML;
56 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
57 import com.google.gwt.user.client.ui.Hidden;
58 import com.google.gwt.user.client.ui.HorizontalPanel;
59 import com.google.gwt.user.client.ui.Label;
60 import com.google.gwt.user.client.ui.VerticalPanel;
61
62 /**
63  * The 'File upload' dialog box implementation.
64  */
65 public class FileUploadDialog extends DialogBox {
66
67     public static final boolean DONE = true;
68
69         /**
70          * The Form element that performs the file upload.
71          */
72         private final FormPanel form = new FormPanel();
73
74         private final FileUpload upload = new FileUpload();
75
76         private final Label filenameLabel = new Label();
77
78     private final Label foldernameLabel = new Label();
79
80     private Button submit;
81
82         protected Folder folder;
83
84     protected Pithos app;
85
86         /**
87          * The widget's constructor.
88          */
89         public FileUploadDialog() {
90                 // Set the dialog's caption.
91                 setText("File upload");
92                 setAnimationEnabled(true);
93                 // Since we're going to add a FileUpload widget, we'll need to set the
94                 // form to use the POST method, and multipart MIME encoding.
95                 form.setEncoding(FormPanel.ENCODING_MULTIPART);
96                 form.setMethod(FormPanel.METHOD_POST);
97
98                 // Create a panel to hold all of the form widgets.
99                 VerticalPanel panel = new VerticalPanel();
100                 form.setWidget(panel);
101
102         final Hidden auth = new Hidden("X-Auth-Token", "");
103         panel.add(auth);
104                 upload.setName("X-Object-Data");
105                 filenameLabel.setText("");
106                 filenameLabel.setVisible(false);
107                 filenameLabel.setStyleName("props-labels");
108                 HorizontalPanel fileUploadPanel = new HorizontalPanel();
109                 fileUploadPanel.add(filenameLabel);
110                 fileUploadPanel.add(upload);
111                 Grid generalTable = new Grid(2, 2);
112                 generalTable.setText(0, 0, "Folder");
113         generalTable.setWidget(0, 1, foldernameLabel);
114                 generalTable.setText(1, 0, "File");
115                 generalTable.setWidget(1, 1, fileUploadPanel);
116                 generalTable.getCellFormatter().setStyleName(0, 0, "props-labels");
117         generalTable.getCellFormatter().setStyleName(0, 1, "props-values");
118                 generalTable.getCellFormatter().setStyleName(1, 0, "props-labels");
119                 generalTable.getCellFormatter().setStyleName(1, 1, "props-values");
120                 generalTable.setCellSpacing(4);
121
122                 panel.add(generalTable);
123
124                 // Create a panel to hold the buttons.
125                 HorizontalPanel buttons = new HorizontalPanel();
126
127                 // Create the 'upload' button, along with a listener that submits the
128                 // form.
129                 submit = new Button("Upload", new ClickHandler() {
130                         @Override
131                         public void onClick(ClickEvent event) {
132                                 prepareAndSubmit();
133                         }
134                 });
135                 buttons.add(submit);
136                 buttons.setCellHorizontalAlignment(submit, HasHorizontalAlignment.ALIGN_CENTER);
137                 // Create the 'Cancel' button, along with a listener that hides the
138                 // dialog when the button is clicked.
139                 final Button cancel = new Button("Cancel", new ClickHandler() {
140                         @Override
141                         public void onClick(ClickEvent event) {
142                                 hide();
143                         }
144                 });
145                 buttons.add(cancel);
146                 buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);
147                 buttons.setSpacing(8);
148         panel.add(buttons);
149         panel.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);
150
151                 // Add an event handler to the form.
152                 form.addSubmitHandler(new SubmitHandler() {
153
154                         @Override
155                         public void onSubmit(SubmitEvent event) {
156                 auth.setValue(app.getToken()); //This is done here because the app object is not available in the constructor
157                         }
158                 });
159                 form.addSubmitCompleteHandler(new SubmitCompleteHandler() {
160
161                         @Override
162                         public void onSubmitComplete(SubmitCompleteEvent event) {
163                                 // When the form submission is successfully completed, this
164                                 // event is fired. Assuming the service returned a response
165                                 // of type text/html, we can get the result text here (see
166                                 // the FormPanel documentation for further explanation).
167                                 String results = event.getResults();
168
169                                 // Unfortunately the results are never empty, even in
170                                 // the absense of errors, so we have to check for '<pre></pre>'.
171                                 if (results != null && results.length() > 0 && !results.equalsIgnoreCase("<pre></pre>")) {
172                                         GWT.log(results, null);
173                                         app.displayError(results);
174                                 }
175                 app.updateFolder(folder, true);
176                                 hide();
177                         }
178                 });
179
180                 setWidget(form);
181         }
182
183         @Override
184         protected void onPreviewNativeEvent(NativePreviewEvent preview) {
185                 super.onPreviewNativeEvent(preview);
186
187                 NativeEvent evt = preview.getNativeEvent();
188                 if (evt.getType().equals("keydown"))
189                         // Use the popup's key preview hooks to close the dialog when either
190                         // enter or escape is pressed.
191                         switch (evt.getKeyCode()) {
192                                 case KeyCodes.KEY_ENTER:
193                                         prepareAndSubmit();
194                                         break;
195                                 case KeyCodes.KEY_ESCAPE:
196                                         hide();
197                                         break;
198                         }
199         }
200
201         /**
202          * Make any last minute checks and start the upload.
203          */
204         protected void prepareAndSubmit() {
205         if (upload.getFilename().length() == 0) {
206             app.displayError("You must select a file!");
207             return;
208         }
209         final String fname = getFilename(upload.getFilename());
210         String apath = app.getApiPath() + app.getUsername() + folder.getUri() + "/" + fname;
211         form.setAction(apath);
212         submit.setEnabled(false);
213         upload.setVisible(false);
214         filenameLabel.setText(fname);
215         filenameLabel.setVisible(true);
216
217                 if (getFileForName(fname) == null) {
218             form.submit();
219                 }
220                 else {
221                         // We are going to update an existing file, so show a confirmation dialog.
222                         ConfirmationDialog confirm = new ConfirmationDialog("Are you sure " +
223                                         "you want to update " + fname + "?", "Update") {
224
225                                 @Override
226                                 public void cancel() {
227                                         FileUploadDialog.this.hide();
228                                 }
229
230                                 @Override
231                                 public void confirm() {
232                                         form.submit();
233                                 }
234
235                         };
236                         confirm.center();
237                 }
238         }
239
240     /**
241          * Returns the file name from a potential full path argument. Apparently IE
242          * insists on sending the full path name of a file when uploading, forcing
243          * us to trim the extra path info. Since this is only observed on Windows we
244          * get to check for a single path separator value.
245          *
246          * @param name the potentially full path name of a file
247          * @return the file name without extra path information
248          */
249         protected String getFilename(String name) {
250                 int pathSepIndex = name.lastIndexOf("\\");
251                 if (pathSepIndex == -1) {
252                         pathSepIndex = name.lastIndexOf("/");
253                         if (pathSepIndex == -1)
254                                 return name;
255                 }
256                 return name.substring(pathSepIndex + 1);
257         }
258
259         protected File getFileForName(String name){
260                 for (File f : folder.getFiles())
261                         if (!f.isInTrash() && f.getName().equals(name))
262                                 return f;
263                 return null;
264         }
265
266     public void setApp(Pithos app) {
267         this.app = app;
268     }
269
270     public void setFolder(Folder folder) {
271         this.folder = folder;
272         foldernameLabel.setText(folder.getName());
273     }
274 }