Renamed all packages to gr.grnet.pithos.*
[pithos] / web_client / src / gr / grnet / pithos / web / client / Groups.java
1 /*\r
2  * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.\r
3  *\r
4  * This file is part of GSS.\r
5  *\r
6  * GSS is free software: you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation, either version 3 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * GSS is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with GSS.  If not, see <http://www.gnu.org/licenses/>.\r
18  */\r
19 package gr.grnet.pithos.web.client;\r
20 \r
21 import gr.grnet.pithos.web.client.rest.GetCommand;\r
22 import gr.grnet.pithos.web.client.rest.MultipleGetCommand;\r
23 import gr.grnet.pithos.web.client.rest.resource.GroupResource;\r
24 import gr.grnet.pithos.web.client.rest.resource.GroupUserResource;\r
25 import gr.grnet.pithos.web.client.rest.resource.GroupsResource;\r
26 \r
27 import java.util.List;\r
28 \r
29 import com.google.gwt.core.client.GWT;\r
30 import com.google.gwt.dom.client.NativeEvent;\r
31 import com.google.gwt.event.dom.client.ContextMenuEvent;\r
32 import com.google.gwt.event.dom.client.ContextMenuHandler;\r
33 import com.google.gwt.event.logical.shared.OpenEvent;\r
34 import com.google.gwt.event.logical.shared.OpenHandler;\r
35 import com.google.gwt.event.logical.shared.SelectionEvent;\r
36 import com.google.gwt.event.logical.shared.SelectionHandler;\r
37 import com.google.gwt.resources.client.ClientBundle;\r
38 import com.google.gwt.resources.client.ImageResource;\r
39 import com.google.gwt.user.client.DOM;\r
40 import com.google.gwt.user.client.DeferredCommand;\r
41 import com.google.gwt.user.client.Event;\r
42 import com.google.gwt.user.client.ui.AbstractImagePrototype;\r
43 import com.google.gwt.user.client.ui.Composite;\r
44 import com.google.gwt.user.client.ui.HTML;\r
45 import com.google.gwt.user.client.ui.Tree;\r
46 import com.google.gwt.user.client.ui.TreeItem;\r
47 \r
48 /**\r
49  * A component that displays a list of the user's groups.\r
50  */\r
51 public class Groups extends Composite implements SelectionHandler, OpenHandler {\r
52 \r
53         /**\r
54          * An image bundle for this widget.\r
55          */\r
56         public interface Images extends Tree.Resources, ClientBundle, FileMenu.Images, EditMenu.Images, GroupMenu.Images, MessagePanel.Images {\r
57 \r
58                 /**\r
59                  * Will bundle the file 'groupevent.png' residing in the package\r
60                  * 'gr.grnet.pithos.web.resources'.\r
61                  *\r
62                  * @return the image prototype\r
63                  */\r
64                 @Source("gr/grnet/pithos/resources/groupevent.png")\r
65                 ImageResource groupImage();\r
66 \r
67                 @Override\r
68                 @Source("gr/grnet/pithos/resources/editdelete.png")\r
69                 ImageResource delete();\r
70 \r
71         }\r
72 \r
73         /**\r
74          * cached latest group selection (for selecting and expanding on refresh)\r
75          */\r
76         private String selectedGroup = null;\r
77 \r
78         /**\r
79          * The tree widget that displays the groups.\r
80          */\r
81         private Tree tree;\r
82 \r
83         /**\r
84          * A cached copy of the currently selected group widget.\r
85          */\r
86         private TreeItem current;\r
87 \r
88         /**\r
89          * A cached copy of the previously selected group widget.\r
90          */\r
91         private TreeItem previous;\r
92 \r
93         /**\r
94          * The widget's image bundle.\r
95          */\r
96         private final Images images;\r
97 \r
98         private GroupContextMenu menu;\r
99 \r
100         /**\r
101          * Constructs a new groups widget with a bundle of images.\r
102          *\r
103          * @param newImages a bundle that provides the images for this widget\r
104          */\r
105         public Groups(final Images newImages) {\r
106 \r
107                 images = newImages;\r
108                 menu = new GroupContextMenu(images);\r
109                 tree = new Tree(newImages);\r
110                 this.addHandler(new ContextMenuHandler() {\r
111 \r
112                         @Override\r
113                         public void onContextMenu(ContextMenuEvent event) {\r
114                                 if(current==null) return;\r
115                                 int left = current.getAbsoluteLeft() + 40;\r
116                                 int top = current.getAbsoluteTop() + 20;\r
117                                 showPopup(left, top);\r
118 \r
119                         }\r
120                 }, ContextMenuEvent.getType());\r
121                 tree.getElement().setId("groupsList.tree");\r
122                 tree.addSelectionHandler(this);\r
123                 tree.addOpenHandler(this);\r
124                 tree.setAnimationEnabled(true);\r
125                 initWidget(tree);\r
126                 this.getElement().setAttribute("id", "CreativeFilesPanel");\r
127                 setStylePrimaryName("pithos-Groups");\r
128                 sinkEvents(Event.ONCONTEXTMENU);\r
129                 sinkEvents(Event.ONMOUSEUP);\r
130                 sinkEvents(Event.ONDBLCLICK);\r
131                 sinkEvents(Event.KEYEVENTS);\r
132         }\r
133 \r
134 \r
135         /**\r
136          * Make an RPC call to retrieve the groups that belong to the specified\r
137          * user.\r
138          */\r
139         public void updateGroups() {\r
140                 GetCommand<GroupsResource> gg = new GetCommand<GroupsResource>(GroupsResource.class, GSS.get().getCurrentUserResource().getGroupsPath(),null){\r
141 \r
142                         @Override\r
143                         public void onComplete() {\r
144                                 GroupsResource res = getResult();\r
145                                 MultipleGetCommand<GroupResource> ga = new MultipleGetCommand<GroupResource>(GroupResource.class, res.getGroupPaths().toArray(new String[]{}), null){\r
146 \r
147                                         @Override\r
148                                         public void onComplete() {\r
149                                                 List<GroupResource> groupList = getResult();\r
150                                                 tree.clear();\r
151                                                 for (int i = 0; i < groupList.size(); i++) {\r
152                                                         final TreeItem item = new TreeItem();\r
153                                                         item.setWidget(imageItemHTML(images.groupImage(), groupList.get(i).getName(),item));\r
154                                                         item.setUserObject(groupList.get(i));                                                   \r
155                                                         tree.addItem(item);\r
156                                                         updateUsers(item);\r
157                                                 }\r
158                                         }\r
159 \r
160                                         @Override\r
161                                         public void onError(Throwable t) {\r
162                                                 GWT.log("", t);\r
163                                         }\r
164 \r
165                                         @Override\r
166                                         public void onError(String p, Throwable throwable) {\r
167                                                 GWT.log("Path:"+p, throwable);\r
168                                         }\r
169                                 };\r
170                                 DeferredCommand.addCommand(ga);\r
171                         }\r
172 \r
173                         @Override\r
174                         public void onError(Throwable t) {\r
175 \r
176                         }\r
177                 };\r
178                 DeferredCommand.addCommand(gg);\r
179         }\r
180 \r
181         /**\r
182          *  update status panel with currently showing file stats\r
183          */\r
184         public void updateCurrentlyShowingStats() {\r
185                 GSS.get().getStatusPanel().updateCurrentlyShowing(null); //clear stats - nothing to show for the groups tab\r
186         }\r
187 \r
188         /**\r
189          * A helper method to simplify adding tree items that have attached images.\r
190          *\r
191          * @param parent the tree item to which the new item will be added.\r
192          * @param title the text associated with this item.\r
193          * @param imageProto\r
194          * @return the new tree item\r
195          */\r
196         private TreeItem addImageItem(final TreeItem parent, final String title, final ImageResource imageProto) {\r
197                 final TreeItem item = new TreeItem();\r
198                 item.setWidget(imageItemHTML(imageProto, title,item));\r
199                 parent.addItem(item);\r
200                 return item;\r
201         }\r
202 \r
203         /**\r
204          * Generates HTML for a tree item with an attached icon.\r
205          *\r
206          * @param imageProto the icon image\r
207          * @param title the title of the item\r
208          * @return the resultant HTML\r
209          */\r
210         private HTML imageItemHTML(final ImageResource imageProto, final String title,final TreeItem item) {\r
211                 final HTML link = new HTML("<a class='hidden-link' href='javascript:;'>" + "<span id='groupsList."+title+"'>" + AbstractImagePrototype.create(imageProto).getHTML() + "&nbsp;" + title + "</span>" + "</a>"){\r
212                         @Override\r
213                         public void onBrowserEvent(Event event) {\r
214                                 switch (DOM.eventGetType(event)) {\r
215                                         case Event.ONMOUSEDOWN:\r
216                                                 if (DOM.eventGetButton(event) == NativeEvent.BUTTON_RIGHT || DOM.eventGetButton(event) == NativeEvent.BUTTON_LEFT)\r
217                                                         onSelection(item);\r
218                                                 break;\r
219                                         case Event.ONCONTEXTMENU:\r
220                                                 showPopup(event.getClientX(), event.getClientY());\r
221                                                 event.preventDefault();\r
222                                                 event.stopPropagation();\r
223                                                 break;\r
224                                 }\r
225                                 super.onBrowserEvent(event);\r
226 \r
227                         }\r
228                 };                      \r
229                 link.sinkEvents(Event.ONMOUSEDOWN);\r
230                 link.sinkEvents(Event.ONCONTEXTMENU);\r
231                 link.sinkEvents(Event.ONCLICK);\r
232                 link.sinkEvents(Event.ONKEYDOWN);               \r
233                 return link;\r
234         }\r
235 \r
236 \r
237 \r
238         protected void showPopup(final int x, final int y) {\r
239                 menu.hide();\r
240                 menu = new GroupContextMenu(images);\r
241                 menu.setPopupPosition(x, y);\r
242                 menu.show();\r
243         }\r
244 \r
245 \r
246 \r
247         /**\r
248          * Generate an RPC request to retrieve the users of the specified group for\r
249          * display.\r
250          *\r
251          * @param groupItem the TreeItem widget that corresponds to the requested\r
252          *            group\r
253          */\r
254         void updateUsers(final TreeItem groupItem) {\r
255                 if(groupItem.getUserObject() instanceof GroupResource){\r
256                         GroupResource res = (GroupResource) groupItem.getUserObject();\r
257                         MultipleGetCommand<GroupUserResource> gu = new MultipleGetCommand<GroupUserResource>(GroupUserResource.class, res.getUserPaths().toArray(new String[]{}), null){\r
258                                 @Override\r
259                                 public void onComplete() {\r
260                                         List<GroupUserResource> users = getResult();\r
261                                         groupItem.removeItems();\r
262                                         for (int i = 0; i < users.size(); i++) {\r
263                                                 final TreeItem userItem = addImageItem(groupItem, users.get(i).getName() + " &lt;" + users.get(i).getUsername() + "&gt;", images.permUser());\r
264                                                 userItem.setUserObject(users.get(i));\r
265                                         }\r
266                                         if (selectedGroup != null && groupItem.getText().equals(selectedGroup)) {\r
267                                                 //SelectionEvent.fire(tree, groupItem);;\r
268                                                 onSelection(groupItem);\r
269                                                 groupItem.setState(true);\r
270                                         }\r
271                                 }\r
272 \r
273                                 @Override\r
274                                 public void onError(Throwable t) {\r
275                                         GWT.log("", t);\r
276                                 }\r
277 \r
278                                 @Override\r
279                                 public void onError(String p, Throwable throwable) {\r
280                                         GWT.log("Path:"+p, throwable);\r
281                                 }\r
282                         };\r
283                         DeferredCommand.addCommand(gu);\r
284                 }\r
285 \r
286         }\r
287 \r
288         /**\r
289          * Retrieve the current.\r
290          *\r
291          * @return the current\r
292          */\r
293         TreeItem getCurrent() {\r
294                 return current;\r
295         }\r
296 \r
297         /**\r
298          * Modify the current.\r
299          *\r
300          * @param newCurrent the current to set\r
301          */\r
302         void setCurrent(final TreeItem newCurrent) {\r
303                 current = newCurrent;\r
304         }\r
305 \r
306         /**\r
307          * Retrieve the previous.\r
308          *\r
309          * @return the previous\r
310          */\r
311         private TreeItem getPrevious() {\r
312                 return previous;\r
313         }\r
314 \r
315         /**\r
316          * Modify the previous.\r
317          *\r
318          * @param newPrevious the previous to set\r
319          */\r
320         private void setPrevious(final TreeItem newPrevious) {\r
321                 previous = newPrevious;\r
322         }\r
323 \r
324         @Override\r
325         public void setVisible(final boolean visible) {\r
326                 super.setVisible(visible);\r
327                 if (visible)\r
328                         updateGroups();\r
329         }\r
330 \r
331         @Override\r
332         public void onSelection(SelectionEvent event) {\r
333                 final TreeItem item = (TreeItem)event.getSelectedItem();\r
334                 onSelection(item);\r
335 \r
336         }\r
337 \r
338         private void onSelection(TreeItem item){\r
339                 final Object selected = item.getUserObject();\r
340                 // Preserve the previously selected item, so that the current's\r
341                 // onClick() method gets a chance to find it.\r
342                 if (getPrevious() != null)\r
343                         getPrevious().getWidget().removeStyleName("pithos-SelectedRow");\r
344                 setCurrent(item);\r
345                 getCurrent().getWidget().addStyleName("pithos-SelectedRow");\r
346                 setPrevious(getCurrent());\r
347                 GSS.get().setCurrentSelection(selected);\r
348                 //cache the latest top level node (group) for selecting and expanding on refresh\r
349                 if (item.getParentItem() == null)\r
350                         selectedGroup = item.getText();\r
351                 else\r
352                         selectedGroup = item.getParentItem().getText();\r
353         }\r
354 \r
355         @Override\r
356         public void onOpen(OpenEvent event) {\r
357                 final TreeItem item = (TreeItem) event.getTarget();\r
358                 updateUsers(item);\r
359         }\r
360 }\r