refresh correctly root node when it has no children
[pithos] / src / gr / ebs / gss / client / FileMenu.java
1 /*
2  * Copyright 2007, 2008, 2009, 2010 Electronic Business Systems Ltd.
3  *
4  * This file is part of GSS.
5  *
6  * GSS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GSS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 package gr.ebs.gss.client;
20
21 import gr.ebs.gss.client.commands.EmptyTrashCommand;
22 import gr.ebs.gss.client.commands.NewFolderCommand;
23 import gr.ebs.gss.client.commands.PropertiesCommand;
24 import gr.ebs.gss.client.commands.RefreshCommand;
25 import gr.ebs.gss.client.commands.UploadFileCommand;
26 import gr.ebs.gss.client.rest.RestCommand;
27 import gr.ebs.gss.client.rest.resource.FileResource;
28 import gr.ebs.gss.client.rest.resource.GroupUserResource;
29 import gr.ebs.gss.client.rest.resource.OtherUserResource;
30 import gr.ebs.gss.client.rest.resource.OthersResource;
31 import gr.ebs.gss.client.rest.resource.RestResource;
32 import gr.ebs.gss.client.rest.resource.SharedResource;
33 import gr.ebs.gss.client.rest.resource.TrashFolderResource;
34 import gr.ebs.gss.client.rest.resource.TrashResource;
35
36 import java.util.List;
37
38 import com.google.gwt.event.dom.client.ClickEvent;
39 import com.google.gwt.event.dom.client.ClickHandler;
40 import com.google.gwt.http.client.URL;
41 import com.google.gwt.resources.client.ClientBundle;
42 import com.google.gwt.resources.client.ImageResource;
43 import com.google.gwt.user.client.Command;
44 import com.google.gwt.user.client.ui.AbstractImagePrototype;
45 import com.google.gwt.user.client.ui.MenuBar;
46 import com.google.gwt.user.client.ui.MenuItem;
47 import com.google.gwt.user.client.ui.PopupPanel;
48 import com.google.gwt.user.client.ui.TreeItem;
49
50 /**
51  * The 'File' menu implementation.
52  */
53 public class FileMenu extends PopupPanel implements ClickHandler {
54
55         /**
56          * The widget's images.
57          */
58         private final Images images;
59
60         /**
61          * An image bundle for this widgets images.
62          */
63         public interface Images extends ClientBundle,FilePropertiesDialog.Images {
64
65                 @Source("gr/ebs/gss/resources/folder_new.png")
66                 ImageResource folderNew();
67
68                 @Source("gr/ebs/gss/resources/folder_outbox.png")
69                 ImageResource fileUpdate();
70
71                 @Source("gr/ebs/gss/resources/view_text.png")
72                 ImageResource viewText();
73
74                 @Override
75                 @Source("gr/ebs/gss/resources/folder_inbox.png")
76                 ImageResource download();
77
78                 @Source("gr/ebs/gss/resources/trashcan_empty.png")
79                 ImageResource emptyTrash();
80
81                 @Source("gr/ebs/gss/resources/internet.png")
82                 ImageResource sharing();
83
84                 @Source("gr/ebs/gss/resources/refresh.png")
85                 ImageResource refresh();
86 }
87
88         final MenuBar contextMenu = new MenuBar(true);
89
90         /**
91          * The widget's constructor.
92          *
93          * @param _images the image bundle passed on by the parent object
94          */
95         public FileMenu(final Images _images) {
96                 // The popup's constructor's argument is a boolean specifying that it
97                 // auto-close itself when the user clicks outside of it.
98                 super(true);
99                 setAnimationEnabled(true);
100                 images = _images;
101                 add(contextMenu);
102
103         }
104
105         @Override
106         public void onClick(ClickEvent event) {
107                 final FileMenu menu = new FileMenu(images);
108                 final int left = event.getRelativeElement().getAbsoluteLeft();
109                 final int top = event.getRelativeElement().getAbsoluteTop() + event.getRelativeElement().getOffsetHeight();
110                 menu.setPopupPosition(left, top);
111                 menu.show();
112
113         }
114
115
116         /**
117          * Do some validation before downloading a file.
118          */
119         void preDownloadCheck() {
120                 Object selection = GSS.get().getCurrentSelection();
121                 if (selection == null || !(selection instanceof FileResource)) {
122                         GSS.get().displayError("You have to select a file first");
123                         return;
124                 }
125         }
126
127         /**
128          * Create a download link for the respective menu item, if the currently
129          * selected object is a file.
130          *
131          * @param link a String array with two elements that is modified so that the
132          *            first position contains the opening tag and the second one the
133          *            closing tag
134          * @param forceDownload If true, link will be such that browser should ask for filename
135          *                              and save location
136          */
137         void createDownloadLink(String[] link, boolean forceDownload) {
138                 String downloadURL = getDownloadURL();
139                 if (!downloadURL.isEmpty()) {
140                         link[0] = "<a id ='topMenu.file.download' class='hidden-link' href='" + downloadURL
141                                         + (forceDownload ? "&dl=1" : "") + "' target='_blank'>";
142                         link[1] = "</a>";
143                 }
144         }
145
146         public String getDownloadURL() {
147                 GSS app = GSS.get();
148                 Object selection = app.getCurrentSelection();
149                 if (selection != null && selection instanceof FileResource) {
150                         FileResource file = (FileResource) selection;
151                         return getDownloadURL(file);
152                 }
153                 return "";
154         }
155
156         public String getDownloadURL(FileResource file) {
157                 GSS app = GSS.get();
158                 if (file != null) {
159                         String dateString = RestCommand.getDate();
160                         String resource = file.getUri().substring(app.getApiPath().length()-1,file.getUri().length());
161                         String sig = app.getCurrentUserResource().getUsername()+" "+RestCommand.calculateSig("GET", dateString, resource, RestCommand.base64decode(app.getToken()));
162                         return file.getUri() + "?Authorization=" + URL.encodeComponent(sig) + "&Date="+URL.encodeComponent(dateString);
163                 }
164                 return "";
165         }
166
167         public MenuBar createMenu() {
168                 contextMenu.clearItems();
169                 contextMenu.setAutoOpen(false);
170                 final Command downloadCmd = new Command() {
171
172                         @Override
173                         public void execute() {
174                                 hide();
175                                 preDownloadCheck();
176                         }
177                 };
178                 //
179                 RestResource selectedItem = GSS.get().getTreeView().getSelection();
180                 boolean downloadVisible = GSS.get().getCurrentSelection() != null && GSS.get().getCurrentSelection() instanceof FileResource;
181                 boolean propertiesVisible = !(selectedItem != null && (selectedItem instanceof TrashResource || selectedItem instanceof TrashFolderResource || selectedItem instanceof SharedResource || selectedItem instanceof OthersResource || selectedItem instanceof OtherUserResource 
182                                         //|| folders.isOthersShared(selectedItem) || selectedItem.getUserObject() instanceof GroupUserResource 
183                                         || GSS.get().getCurrentSelection() instanceof List));
184                 boolean newFolderVisible = !(selectedItem != null && (selectedItem instanceof TrashResource || selectedItem instanceof TrashFolderResource || selectedItem instanceof SharedResource || selectedItem instanceof OthersResource || selectedItem instanceof OtherUserResource));
185                 boolean uploadVisible = !(selectedItem != null && (selectedItem instanceof TrashResource || selectedItem instanceof TrashFolderResource || selectedItem instanceof SharedResource || selectedItem instanceof OthersResource || selectedItem instanceof OtherUserResource));
186                 if(newFolderVisible){
187                         MenuItem newFolderItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.folderNew()).getHTML() + "&nbsp;New Folder</span>", true, new NewFolderCommand(this, images));
188                         newFolderItem.getElement().setId("topMenu.file.newFolder");
189                         contextMenu.addItem(newFolderItem);                     
190                 }
191                 if(uploadVisible){
192                         MenuItem uploadItem = new MenuItem("<span id='topMenu.file.upload'>" + AbstractImagePrototype.create(images.fileUpdate()).getHTML() + "&nbsp;Upload</span>", true, new UploadFileCommand(this));                        
193                         contextMenu.addItem(uploadItem);
194                 }
195                 if (downloadVisible) {
196                         String[] link = {"", ""};
197                         createDownloadLink(link, false);
198                         
199                         MenuItem downloadItem = new MenuItem("<span>" + link[0] + AbstractImagePrototype.create(images.download()).getHTML() + "&nbsp;Download" + link[1] + "</span>", true, downloadCmd);
200                         contextMenu.addItem(downloadItem);
201                         
202                         createDownloadLink(link, true);
203                         
204                         MenuItem saveAsItem = new MenuItem("<span>" + link[0] + AbstractImagePrototype.create(images.download()).getHTML() + "&nbsp;Save As" + link[1] + "</span>", true, downloadCmd);                 
205                         contextMenu.addItem(saveAsItem);
206                 }
207                 MenuItem emptyTrashItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.emptyTrash()).getHTML() + "&nbsp;Empty Trash</span>", true, new EmptyTrashCommand(this));
208                 emptyTrashItem.getElement().setId("topMenu.file.emptyTrash");
209                 contextMenu.addItem(emptyTrashItem);
210                 
211                 MenuItem refreshItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.refresh()).getHTML() + "&nbsp;Refresh</span>", true, new RefreshCommand(this, images));
212                 refreshItem.getElement().setId("topMenu.file.refresh");
213                 contextMenu.addItem(refreshItem);
214                 
215                 MenuItem sharingItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.sharing()).getHTML() + "&nbsp;Sharing</span>", true, new PropertiesCommand(this, images, 1));
216                 sharingItem.getElement().setId("topMenu.file.sharing");
217                 contextMenu.addItem(sharingItem)
218                                         .setVisible(propertiesVisible);
219                 
220                 MenuItem propertiesItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.viewText()).getHTML() + "&nbsp;Properties</span>", true, new PropertiesCommand(this, images, 0));
221                 propertiesItem.getElement().setId("topMenu.file.properties");
222                 contextMenu.addItem(propertiesItem)
223                                         .setVisible(propertiesVisible);
224                 return contextMenu;
225         }
226
227 }