86e0d263645bf318cf28284e91d25bae535d3a10
[pithos-web-client] / src / gr / grnet / pithos / web / client / FilePropertiesDialog.java
1 /*\r
2  * Copyright 2011 GRNET S.A. All rights reserved.\r
3  *\r
4  * Redistribution and use in source and binary forms, with or\r
5  * without modification, are permitted provided that the following\r
6  * conditions are met:\r
7  *\r
8  *   1. Redistributions of source code must retain the above\r
9  *      copyright notice, this list of conditions and the following\r
10  *      disclaimer.\r
11  *\r
12  *   2. Redistributions in binary form must reproduce the above\r
13  *      copyright notice, this list of conditions and the following\r
14  *      disclaimer in the documentation and/or other materials\r
15  *      provided with the distribution.\r
16  *\r
17  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS\r
18  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
20  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR\r
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\r
24  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\r
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
27  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
28  * POSSIBILITY OF SUCH DAMAGE.\r
29  *\r
30  * The views and conclusions contained in the software and\r
31  * documentation are those of the authors and should not be\r
32  * interpreted as representing official policies, either expressed\r
33  * or implied, of GRNET S.A.\r
34  */\r
35 package gr.grnet.pithos.web.client;\r
36 \r
37 import com.google.gwt.core.client.Scheduler;\r
38 import gr.grnet.pithos.web.client.foldertree.File;\r
39 import gr.grnet.pithos.web.client.foldertree.Resource;\r
40 import gr.grnet.pithos.web.client.rest.PostCommand;\r
41 import gr.grnet.pithos.web.client.rest.PutRequest;\r
42 import gr.grnet.pithos.web.client.rest.RestException;\r
43 \r
44 import com.google.gwt.core.client.GWT;\r
45 import com.google.gwt.event.dom.client.ClickEvent;\r
46 import com.google.gwt.event.dom.client.ClickHandler;\r
47 import com.google.gwt.i18n.client.DateTimeFormat;\r
48 import com.google.gwt.json.client.JSONBoolean;\r
49 import com.google.gwt.json.client.JSONObject;\r
50 import com.google.gwt.resources.client.ClientBundle;\r
51 import com.google.gwt.resources.client.ImageResource;\r
52 import com.google.gwt.user.client.Command;\r
53 import com.google.gwt.user.client.DeferredCommand;\r
54 import com.google.gwt.user.client.ui.Button;\r
55 import com.google.gwt.user.client.ui.CheckBox;\r
56 import com.google.gwt.user.client.ui.DecoratedTabPanel;\r
57 import com.google.gwt.user.client.ui.DisclosurePanel;\r
58 import com.google.gwt.user.client.ui.FlexTable;\r
59 import com.google.gwt.user.client.ui.FlowPanel;\r
60 import com.google.gwt.user.client.ui.FocusPanel;\r
61 import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
62 import com.google.gwt.user.client.ui.HorizontalPanel;\r
63 import com.google.gwt.user.client.ui.TextBox;\r
64 import com.google.gwt.user.client.ui.VerticalPanel;\r
65 \r
66 /**\r
67  * The 'File properties' dialog box implementation.\r
68  *\r
69  */\r
70 public class FilePropertiesDialog extends AbstractPropertiesDialog {\r
71 \r
72         private PermissionsList permList;\r
73 \r
74         private CheckBox readForAll;\r
75 \r
76         /**\r
77          * An image bundle for this widgets images.\r
78          */\r
79         public interface Images extends ClientBundle,MessagePanel.Images {\r
80 \r
81                 @Source("gr/grnet/pithos/resources/edit_user.png")\r
82                 ImageResource permUser();\r
83 \r
84                 @Source("gr/grnet/pithos/resources/groupevent.png")\r
85                 ImageResource permGroup();\r
86 \r
87                 @Source("gr/grnet/pithos/resources/editdelete.png")\r
88                 ImageResource delete();\r
89 \r
90                 @Source("gr/grnet/pithos/resources/db_update.png")\r
91                 ImageResource restore();\r
92 \r
93                 @Source("gr/grnet/pithos/resources/folder_inbox.png")\r
94                 ImageResource download();\r
95         }\r
96 \r
97         /**\r
98          * The widget that holds the name of the file.\r
99          */\r
100         private TextBox name = new TextBox();\r
101 \r
102         private final CheckBox versioned = new CheckBox();\r
103 \r
104         final File file;\r
105 \r
106         private String userFullName;\r
107 \r
108     private Pithos app;\r
109 \r
110         /**\r
111          * The widget's constructor.\r
112          */\r
113         public FilePropertiesDialog(Pithos _app, File _file) {\r
114         app = _app;\r
115         file = _file;\r
116 \r
117                 // Set the dialog's caption.\r
118                 setText("File properties");\r
119 \r
120 \r
121 //              permList = new PermissionsList(images, file.getPermissions(), file.getOwner());\r
122 \r
123                 // Outer contains inner and buttons.\r
124                 final VerticalPanel outer = new VerticalPanel();\r
125                 final FocusPanel focusPanel = new FocusPanel(outer);\r
126                 // Inner contains generalPanel and permPanel.\r
127                 inner = new DecoratedTabPanel();\r
128                 inner.setAnimationEnabled(true);\r
129 \r
130 \r
131         inner.add(createGeneralPanel(), "General");\r
132 \r
133         inner.add(createSharingPanel(), "Sharing");\r
134 \r
135         inner.add(createVersionPanel(), "Versions");\r
136 \r
137         inner.selectTab(0);\r
138 \r
139         outer.add(inner);\r
140 \r
141                 final HorizontalPanel buttons = new HorizontalPanel();\r
142                 // Create the 'OK' button, along with a listener that hides the dialog\r
143                 // when the button is clicked.\r
144                 final Button ok = new Button("OK", new ClickHandler() {\r
145                         @Override\r
146                         public void onClick(ClickEvent event) {\r
147                                 accept();\r
148                                 closeDialog();\r
149                         }\r
150                 });\r
151 \r
152                 buttons.add(ok);\r
153                 buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);\r
154                 // Create the 'Cancel' button, along with a listener that hides the\r
155                 // dialog when the button is clicked.\r
156                 final Button cancel = new Button("Cancel", new ClickHandler() {\r
157                         @Override\r
158                         public void onClick(ClickEvent event) {\r
159                                 closeDialog();\r
160                         }\r
161                 });\r
162                 buttons.add(cancel);\r
163                 buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
164                 buttons.setSpacing(8);\r
165                 buttons.addStyleName("pithos-TabPanelBottom");\r
166 \r
167         outer.add(buttons);\r
168         outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);\r
169         outer.addStyleName("pithos-TabPanelBottom");\r
170 \r
171         focusPanel.setFocus(true);\r
172         setWidget(outer);\r
173 \r
174                 // Asynchronously retrieve the tags defined by this user.\r
175                 DeferredCommand.addCommand(new Command() {\r
176 \r
177                         @Override\r
178                         public void execute() {\r
179 //                              updateTags();\r
180                         }\r
181                 });\r
182         }\r
183 \r
184     private VerticalPanel createGeneralPanel() {\r
185         final VerticalPanel generalPanel = new VerticalPanel();\r
186         final FlexTable generalTable = new FlexTable();\r
187         generalTable.setText(0, 0, "Name");\r
188         generalTable.setText(1, 0, "Folder");\r
189         generalTable.setText(2, 0, "Owner");\r
190         generalTable.setText(3, 0, "Last modified");\r
191 //        generalTable.setText(4, 0, "Tags");\r
192 \r
193         name.setWidth("100%");\r
194         name.setText(file.getName());\r
195         generalTable.setWidget(0, 1, name);\r
196         if(file.getParent() != null)\r
197             generalTable.setText(1, 1, file.getParent().getName());\r
198         else\r
199             generalTable.setText(1, 1, "-");\r
200         generalTable.setText(2, 1, file.getOwner());\r
201 \r
202         final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");\r
203         generalTable.setText(3, 1, formatter.format(file.getLastModified()));\r
204 \r
205                 // Get the tags.\r
206 //              StringBuffer tagsBuffer = new StringBuffer();\r
207 //              Iterator i = file.getTags().iterator();\r
208 //              while (i.hasNext()) {\r
209 //                      String tag = (String) i.next();\r
210 //                      tagsBuffer.append(tag).append(", ");\r
211 //              }\r
212 //              if (tagsBuffer.length() > 1)\r
213 //                      tagsBuffer.delete(tagsBuffer.length() - 2, tagsBuffer.length() - 1);\r
214 //              initialTagText = tagsBuffer.toString();\r
215 //              tags.setWidth("100%");\r
216 //              tags.getElement().setId("filePropertiesDialog.textBox.tags");\r
217 //              tags.setText(initialTagText);\r
218 //              generalTable.setWidget(4, 1, tags);\r
219 \r
220         generalTable.getFlexCellFormatter().setStyleName(0, 0, "props-labels");\r
221         generalTable.getFlexCellFormatter().setStyleName(1, 0, "props-labels");\r
222         generalTable.getFlexCellFormatter().setStyleName(2, 0, "props-labels");\r
223         generalTable.getFlexCellFormatter().setStyleName(3, 0, "props-labels");\r
224 //        generalTable.getFlexCellFormatter().setStyleName(4, 0, "props-labels");\r
225         generalTable.getFlexCellFormatter().setStyleName(0, 1, "props-values");\r
226         generalTable.getFlexCellFormatter().setStyleName(1, 1, "props-values");\r
227         generalTable.getFlexCellFormatter().setStyleName(2, 1, "props-values");\r
228         generalTable.getFlexCellFormatter().setStyleName(3, 1, "props-values");\r
229 //        generalTable.getFlexCellFormatter().setStyleName(4, 1, "props-values");\r
230         generalTable.setCellSpacing(4);\r
231 \r
232         generalPanel.add(generalTable);\r
233 \r
234         DisclosurePanel allTags = new DisclosurePanel("All tags");\r
235         allTagsContent = new FlowPanel();\r
236         allTagsContent.setWidth("100%");\r
237         allTags.setContent(allTagsContent);\r
238         generalPanel.add(allTags);\r
239         generalPanel.setSpacing(4);\r
240         return generalPanel;\r
241     }\r
242 \r
243     private VerticalPanel createSharingPanel() {\r
244         VerticalPanel permPanel = new VerticalPanel();\r
245 //\r
246 //        permList = new PermissionsList(images, file.getPermissions(), file.getOwner());\r
247 //        permPanel.add(permList);\r
248 //\r
249 //        HorizontalPanel permButtons = new HorizontalPanel();\r
250 //        Button add = new Button("Add Group", new ClickHandler() {\r
251 //            @Override\r
252 //            public void onClick(ClickEvent event) {\r
253 //                PermissionsAddDialog dlg = new PermissionsAddDialog(groups, permList, false);\r
254 //                dlg.center();\r
255 //            }\r
256 //        });\r
257 //        permButtons.add(add);\r
258 //        permButtons.setCellHorizontalAlignment(add, HasHorizontalAlignment.ALIGN_CENTER);\r
259 //\r
260 //        final Button addUser = new Button("Add User", new ClickHandler() {\r
261 //            @Override\r
262 //            public void onClick(ClickEvent event) {\r
263 //                PermissionsAddDialog dlg = new PermissionsAddDialog(groups, permList, true);\r
264 //                dlg.center();\r
265 //            }\r
266 //        });\r
267 //        permButtons.add(addUser);\r
268 //        permButtons.setCellHorizontalAlignment(addUser, HasHorizontalAlignment.ALIGN_CENTER);\r
269 //\r
270 //        permButtons.setSpacing(8);\r
271 //        permButtons.addStyleName("pithos-TabPanelBottom");\r
272 //        permPanel.add(permButtons);\r
273 //\r
274 //        final Label readForAllNote = new Label("When this option is enabled, the file will be readable" +\r
275 //                    " by everyone. By checking this option, you are certifying that you have the right to " +\r
276 //                    "distribute this file and that it does not violate the Terms of Use.", true);\r
277 //        readForAllNote.setVisible(false);\r
278 //        readForAllNote.setStylePrimaryName("pithos-readForAllNote");\r
279 //\r
280 //        readForAll = new CheckBox();\r
281 //        readForAll.setValue(file.isReadForAll());\r
282 //        readForAll.addClickHandler(new ClickHandler() {\r
283 //            @Override\r
284 //            public void onClick(ClickEvent event) {\r
285 //                readForAllNote.setVisible(readForAll.getValue());\r
286 //            }\r
287 //\r
288 //        });\r
289 //\r
290 //        // Only show the read for all permission if the user is the owner.\r
291 //        if (file.getOwner().equals(app.getUsername())) {\r
292 //            final HorizontalPanel permForAll = new HorizontalPanel();\r
293 //            permForAll.add(new Label("Public"));\r
294 //            permForAll.add(readForAll);\r
295 //            permForAll.setSpacing(8);\r
296 //            permForAll.addStyleName("pithos-TabPanelBottom");\r
297 //            permForAll.add(readForAllNote);\r
298 //            permPanel.add(permForAll);\r
299 //        }\r
300 //\r
301 //\r
302 //        final HorizontalPanel pathPanel = new HorizontalPanel();\r
303 //        pathPanel.setWidth("100%");\r
304 //        pathPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);\r
305 //        pathPanel.add(new Label("Link"));\r
306 //        pathPanel.setSpacing(8);\r
307 //        pathPanel.addStyleName("pithos-TabPanelBottom");\r
308 //\r
309 //        TextBox path = new TextBox();\r
310 //        path.setWidth("100%");\r
311 //        path.addClickHandler(new ClickHandler() {\r
312 //            @Override\r
313 //            public void onClick(ClickEvent event) {\r
314 //                Pithos.enableIESelection();\r
315 //                ((TextBox) event.getSource()).selectAll();\r
316 //                Pithos.preventIESelection();\r
317 //            }\r
318 //        });\r
319 //        path.setText(file.getUri());\r
320 //        path.setTitle("Use this link for sharing the file via e-mail, IM, etc. (crtl-C/cmd-C to copy to system clipboard)");\r
321 //        path.setWidth("100%");\r
322 //        path.setReadOnly(true);\r
323 //        pathPanel.add(path);\r
324 //        permPanel.add(pathPanel);\r
325 \r
326         return permPanel;\r
327     }\r
328 \r
329     private VerticalPanel createVersionPanel() {\r
330         VerticalPanel versionPanel = new VerticalPanel();\r
331 \r
332 //        VersionsList verList = new VersionsList(this, images, bodies);\r
333 //        versionPanel.add(verList);\r
334 //\r
335 //        HorizontalPanel vPanel = new HorizontalPanel();\r
336 //\r
337 //              vPanel.setSpacing(8);\r
338 //              vPanel.addStyleName("pithos-TabPanelBottom");\r
339 //              vPanel.add(new Label("Versioned"));\r
340 //\r
341 //              versioned.setValue(file.isVersioned());\r
342 //              vPanel.add(versioned);\r
343 //              versionPanel.add(vPanel);\r
344 //\r
345 //        HorizontalPanel vPanel2 = new HorizontalPanel();\r
346 //              vPanel2.setSpacing(8);\r
347 //              vPanel2.addStyleName("pithos-TabPanelBottom");\r
348 //\r
349 //        HTML removeAllVersion = new HTML("<span>Remove all previous versions?</span>");\r
350 //        vPanel2.add(removeAllVersion);\r
351 //\r
352 //              Button removeVersionsButton = new Button(AbstractImagePrototype.create(images.delete()).getHTML(), new ClickHandler() {\r
353 //                      @Override\r
354 //                      public void onClick(ClickEvent event) {\r
355 //                              ConfirmationDialog confirm = new ConfirmationDialog("Really " +\r
356 //                                              "remove all previous versions?", "Remove") {\r
357 //\r
358 //                                      @Override\r
359 //                                      public void cancel() {\r
360 //                                      }\r
361 //\r
362 //                                      @Override\r
363 //                                      public void confirm() {\r
364 //                                              FilePropertiesDialog.this.closeDialog();\r
365 //                                              removeAllOldVersions();\r
366 //                                      }\r
367 //\r
368 //                              };\r
369 //                              confirm.center();\r
370 //                      }\r
371 //\r
372 //              });\r
373 //              vPanel2.add(removeVersionsButton);\r
374 //        if(!file.isVersioned())\r
375 //            vPanel2.setVisible(false);\r
376 //\r
377 //        versionPanel.add(vPanel2);\r
378 \r
379         return versionPanel;\r
380     }\r
381 \r
382         /**\r
383          * Accepts any change and updates the file\r
384          *\r
385          */\r
386         @Override\r
387         protected void accept() {\r
388                 String newFilename = null;\r
389 //              permList.updatePermissionsAccordingToInput();\r
390 //              Set<PermissionHolder> perms = permList.getPermissions();\r
391 //              JSONObject json = new JSONObject();\r
392                 if (!name.getText().equals(file.getName())) {\r
393                         newFilename = name.getText();\r
394 //                      json.put("name", new JSONString(newFilename));\r
395                 }\r
396 //              if (versioned.getValue() != file.isVersioned())\r
397 //                      json.put("versioned", JSONBoolean.getInstance(versioned.getValue()));\r
398                 //only update the read for all perm if the user is the owner\r
399 //              if (readForAll.getValue() != file.isReadForAll())\r
400 //                      if (file.getOwner().equals(Pithos.get().getCurrentUserResource().getUsername()))\r
401 //                              json.put("readForAll", JSONBoolean.getInstance(readForAll.getValue()));\r
402 //              int i = 0;\r
403 //              if (permList.hasChanges()) {\r
404 //                      GWT.log("Permissions change", null);\r
405 //                      JSONArray perma = new JSONArray();\r
406 //\r
407 //                      for (PermissionHolder p : perms) {\r
408 //                              JSONObject po = new JSONObject();\r
409 //                              if (p.getUser() != null)\r
410 //                                      po.put("user", new JSONString(p.getUser()));\r
411 //                              if (p.getGroup() != null)\r
412 //                                      po.put("group", new JSONString(p.getGroup()));\r
413 //                              po.put("read", JSONBoolean.getInstance(p.isRead()));\r
414 //                              po.put("write", JSONBoolean.getInstance(p.isWrite()));\r
415 //                              po.put("modifyACL", JSONBoolean.getInstance(p.isModifyACL()));\r
416 //                              perma.set(i, po);\r
417 //                              i++;\r
418 //                      }\r
419 //                      json.put("permissions", perma);\r
420 //              }\r
421 //              JSONArray taga = new JSONArray();\r
422 //              i = 0;\r
423 //              if (!tags.getText().equals(initialTagText)) {\r
424 //                      String[] tagset = tags.getText().split(",");\r
425 //                      for (String t : tagset) {\r
426 //                              JSONString to = new JSONString(t);\r
427 //                              taga.set(i, to);\r
428 //                              i++;\r
429 //                      }\r
430 //                      json.put("tags", taga);\r
431 //              }\r
432 //              String jsonString = json.toString();\r
433 //              if(jsonString.equals("{}")){\r
434 //                      GWT.log("NO CHANGES", null);\r
435 //                      return;\r
436 //              }\r
437                 final String newFilenameFinal = newFilename;\r
438 \r
439         if (newFilename == null)\r
440             return;\r
441         String path = app.getApiPath() + app.getUsername() + file.getParent().getUri() + "/" + newFilename;\r
442         PutRequest updateFile = new PutRequest(path) {\r
443             @Override\r
444             public void onSuccess(Resource result) {\r
445                 app.updateFolder(file.getParent());\r
446             }\r
447 \r
448             @Override\r
449             public void onError(Throwable t) {\r
450                 GWT.log("", t);\r
451                 app.displayError("System error modifying file:" + t.getMessage());\r
452             }\r
453         };\r
454         updateFile.setHeader("X-Auth-Token", app.getToken());\r
455         updateFile.setHeader("X-Move-From", file.getUri());\r
456         updateFile.setHeader("Content-Type", file.getContentType());\r
457         Scheduler.get().scheduleDeferred(updateFile);\r
458         }\r
459 \r
460         private void removeAllOldVersions() {\r
461                 JSONObject json = new JSONObject();\r
462                 json.put("versioned", JSONBoolean.getInstance(false));\r
463                 GWT.log(json.toString(), null);\r
464                 PostCommand cf = new PostCommand(file.getUri() + "?update=", json.toString(), 200) {\r
465 \r
466                         @Override\r
467                         public void onComplete() {\r
468                                 toggleVersioned(true);\r
469                         }\r
470 \r
471                         @Override\r
472                         public void onError(Throwable t) {\r
473                                 GWT.log("", t);\r
474                                 if (t instanceof RestException) {\r
475                                         int statusCode = ((RestException) t).getHttpStatusCode();\r
476                                         if (statusCode == 405)\r
477                                                 Pithos.get().displayError("You don't have the necessary permissions");\r
478                                         else if (statusCode == 404)\r
479                                                 Pithos.get().displayError("User in permissions does not exist");\r
480                                         else if (statusCode == 409)\r
481                                                 Pithos.get().displayError("A folder with the same name already exists");\r
482                                         else if (statusCode == 413)\r
483                                                 Pithos.get().displayError("Your quota has been exceeded");\r
484                                         else\r
485                                                 Pithos.get().displayError("Unable to modify file:" + ((RestException) t).getHttpStatusText());\r
486                                 } else\r
487                                         Pithos.get().displayError("System error moifying file:" + t.getMessage());\r
488                         }\r
489                 };\r
490                 DeferredCommand.addCommand(cf);\r
491         }\r
492 \r
493         private void toggleVersioned(boolean versionedValue) {\r
494                 JSONObject json = new JSONObject();\r
495                 json.put("versioned", JSONBoolean.getInstance(versionedValue));\r
496                 GWT.log(json.toString(), null);\r
497                 PostCommand cf = new PostCommand(file.getUri() + "?update=", json.toString(), 200) {\r
498 \r
499                         @Override\r
500                         public void onComplete() {\r
501                                 Pithos.get().getTreeView().refreshCurrentNode(false);\r
502                         }\r
503 \r
504                         @Override\r
505                         public void onError(Throwable t) {\r
506                                 GWT.log("", t);\r
507                                 if (t instanceof RestException) {\r
508                                         int statusCode = ((RestException) t).getHttpStatusCode();\r
509                                         if (statusCode == 405)\r
510                                                 Pithos.get().displayError("You don't have the necessary permissions");\r
511                                         else if (statusCode == 404)\r
512                                                 Pithos.get().displayError("User in permissions does not exist");\r
513                                         else if (statusCode == 409)\r
514                                                 Pithos.get().displayError("A folder with the same name already exists");\r
515                                         else if (statusCode == 413)\r
516                                                 Pithos.get().displayError("Your quota has been exceeded");\r
517                                         else\r
518                                                 Pithos.get().displayError("Unable to modify file:" + ((RestException) t).getHttpStatusText());\r
519                                 } else\r
520                                         Pithos.get().displayError("System error moifying file:" + t.getMessage());\r
521                         }\r
522                 };\r
523                 DeferredCommand.addCommand(cf);\r
524         }\r
525 \r
526 }\r