fix sharing icon and popup for my shared items and others
[pithos] / src / gr / ebs / gss / 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.ebs.gss.client;\r
20 \r
21 import gr.ebs.gss.client.rest.GetCommand;\r
22 import gr.ebs.gss.client.rest.MultipleGetCommand;\r
23 import gr.ebs.gss.client.rest.resource.GroupResource;\r
24 import gr.ebs.gss.client.rest.resource.GroupUserResource;\r
25 import gr.ebs.gss.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.ebs.gss.resources'.\r
61                  *\r
62                  * @return the image prototype\r
63                  */\r
64                 @Source("gr/ebs/gss/resources/groupevent.png")\r
65                 ImageResource groupImage();\r
66 \r
67                 @Source("gr/ebs/gss/resources/editdelete.png")\r
68                 ImageResource delete();\r
69 \r
70         }\r
71         private boolean ctrlKeyPressed = false;\r
72 \r
73         private boolean leftClicked = false;\r
74 \r
75         private boolean rightClicked = false;\r
76 \r
77         /**\r
78          * cached latest group selection (for selecting and expanding on refresh)\r
79          */\r
80         private String selectedGroup = null;\r
81 \r
82         /**\r
83          * The tree widget that displays the groups.\r
84          */\r
85         private Tree tree;\r
86 \r
87         /**\r
88          * A cached copy of the currently selected group widget.\r
89          */\r
90         private TreeItem current;\r
91 \r
92         /**\r
93          * A cached copy of the previously selected group widget.\r
94          */\r
95         private TreeItem previous;\r
96 \r
97         /**\r
98          * A cached copy of the currently changed group widget.\r
99          */\r
100         private TreeItem changed;\r
101 \r
102         /**\r
103          * The widget's image bundle.\r
104          */\r
105         private final Images images;\r
106 \r
107         private GroupContextMenu menu;\r
108 \r
109         private boolean showMenu=false;\r
110         /**\r
111          * Constructs a new groups widget with a bundle of images.\r
112          *\r
113          * @param newImages a bundle that provides the images for this widget\r
114          */\r
115         public Groups(final Images newImages) {\r
116 \r
117                 images = newImages;\r
118                 menu = new GroupContextMenu(images);\r
119                 tree = new Tree(newImages);\r
120                 this.addHandler(new ContextMenuHandler() {\r
121 \r
122                         @Override\r
123                         public void onContextMenu(ContextMenuEvent event) {\r
124                                 if(current==null) return;\r
125                                 int left = current.getAbsoluteLeft() + 40;\r
126                                 int top = current.getAbsoluteTop() + 20;\r
127                                 showPopup(left, top);\r
128 \r
129                         }\r
130                 }, ContextMenuEvent.getType());\r
131                 tree.addSelectionHandler(this);\r
132                 tree.addOpenHandler(this);\r
133                 tree.setAnimationEnabled(true);\r
134                 initWidget(tree);\r
135                 setStylePrimaryName("gss-Groups");\r
136                 sinkEvents(Event.ONCONTEXTMENU);\r
137                 sinkEvents(Event.ONMOUSEUP);\r
138                 sinkEvents(Event.ONDBLCLICK);\r
139         }\r
140 \r
141 \r
142         /**\r
143          * Make an RPC call to retrieve the groups that belong to the specified\r
144          * user.\r
145          */\r
146         public void updateGroups() {\r
147                 GetCommand<GroupsResource> gg = new GetCommand<GroupsResource>(GroupsResource.class, GSS.get().getCurrentUserResource().getGroupsPath(),null){\r
148 \r
149                         @Override\r
150                         public void onComplete() {\r
151                                 GroupsResource res = getResult();\r
152                                 MultipleGetCommand<GroupResource> ga = new MultipleGetCommand<GroupResource>(GroupResource.class, res.getGroupPaths().toArray(new String[]{}), null){\r
153 \r
154                                         @Override\r
155                                         public void onComplete() {\r
156                                                 List<GroupResource> groupList = getResult();\r
157                                                 tree.clear();\r
158                                                 for (int i = 0; i < groupList.size(); i++) {\r
159                                                         final TreeItem item = new TreeItem();\r
160                                                         item.setWidget(imageItemHTML(images.groupImage(), groupList.get(i).getName(),item));\r
161                                                         item.setUserObject(groupList.get(i));\r
162                                                         tree.addItem(item);\r
163                                                         updateUsers(item);\r
164                                                 }\r
165                                         }\r
166 \r
167                                         @Override\r
168                                         public void onError(Throwable t) {\r
169                                                 GWT.log("", t);\r
170                                         }\r
171 \r
172                                         @Override\r
173                                         public void onError(String p, Throwable throwable) {\r
174                                                 GWT.log("Path:"+p, throwable);\r
175                                         }\r
176                                 };\r
177                                 DeferredCommand.addCommand(ga);\r
178                         }\r
179 \r
180                         @Override\r
181                         public void onError(Throwable t) {\r
182 \r
183                         }\r
184                 };\r
185                 DeferredCommand.addCommand(gg);\r
186         }\r
187 \r
188         /**\r
189          *  update status panel with currently showing file stats\r
190          */\r
191         public void updateCurrentlyShowingStats() {\r
192                 GSS.get().getStatusPanel().updateCurrentlyShowing(null); //clear stats - nothing to show for the groups tab\r
193         }\r
194 \r
195         /**\r
196          * A helper method to simplify adding tree items that have attached images.\r
197          * {@link #addImageItem(TreeItem, String) code}\r
198          *\r
199          * @param parent the tree item to which the new item will be added.\r
200          * @param title the text associated with this item.\r
201          * @param imageProto\r
202          * @return the new tree item\r
203          */\r
204         private TreeItem addImageItem(final TreeItem parent, final String title, final ImageResource imageProto) {\r
205                 final TreeItem item = new TreeItem();\r
206                 item.setWidget(imageItemHTML(imageProto, title,item));\r
207                 parent.addItem(item);\r
208                 return item;\r
209         }\r
210 \r
211         /**\r
212          * Generates HTML for a tree item with an attached icon.\r
213          *\r
214          * @param imageProto the icon image\r
215          * @param title the title of the item\r
216          * @return the resultant HTML\r
217          */\r
218         private HTML imageItemHTML(final ImageResource imageProto, final String title,final TreeItem item) {\r
219                 final HTML link = new HTML("<a class='hidden-link' href='javascript:;'>" + "<span>" + AbstractImagePrototype.create(imageProto).getHTML() + "&nbsp;" + title + "</span>" + "</a>"){\r
220                         @Override\r
221                         public void onBrowserEvent(Event event) {\r
222                                 switch (DOM.eventGetType(event)) {\r
223                                         case Event.ONMOUSEDOWN:\r
224                                                 if (DOM.eventGetButton(event) == NativeEvent.BUTTON_RIGHT || DOM.eventGetButton(event) == NativeEvent.BUTTON_LEFT)\r
225                                                         onSelection(item);\r
226                                                 break;\r
227                                 }\r
228                                 super.onBrowserEvent(event);\r
229 \r
230                         }\r
231                 };\r
232                 link.sinkEvents(Event.ONMOUSEDOWN);\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                 if (getCurrent() == null){\r
240                         GWT.log("[POPUP IS NULL]", null);\r
241                         return;\r
242                 }\r
243                 menu.hide();\r
244                 menu = new GroupContextMenu(images);\r
245                 menu.setPopupPosition(x, y);\r
246                 showMenu=false;\r
247                 menu.show();\r
248         }\r
249 \r
250 \r
251 \r
252         /**\r
253          * Generate an RPC request to retrieve the users of the specified group for\r
254          * display.\r
255          *\r
256          * @param userId the ID of the current user\r
257          * @param groupItem the TreeItem widget that corresponds to the requested\r
258          *            group\r
259          */\r
260         void updateUsers(final TreeItem groupItem) {\r
261                 if(groupItem.getUserObject() instanceof GroupResource){\r
262                         GroupResource res = (GroupResource) groupItem.getUserObject();\r
263                         MultipleGetCommand<GroupUserResource> gu = new MultipleGetCommand<GroupUserResource>(GroupUserResource.class, res.getUserPaths().toArray(new String[]{}), null){\r
264                                 @Override\r
265                                 public void onComplete() {\r
266                                         List<GroupUserResource> users = getResult();\r
267                                         groupItem.removeItems();\r
268                                         for (int i = 0; i < users.size(); i++) {\r
269                                                 final TreeItem userItem = addImageItem(groupItem, users.get(i).getName() + " &lt;" + users.get(i).getUsername() + "&gt;", images.permUser());\r
270                                                 userItem.setUserObject(users.get(i));\r
271                                         }\r
272                                         if (selectedGroup != null && groupItem.getText().equals(selectedGroup)) {\r
273                                                 //SelectionEvent.fire(tree, groupItem);;\r
274                                                 onSelection(groupItem);\r
275                                                 groupItem.setState(true);\r
276                                         }\r
277                                 }\r
278 \r
279                                 @Override\r
280                                 public void onError(Throwable t) {\r
281                                         GWT.log("", t);\r
282                                 }\r
283 \r
284                                 @Override\r
285                                 public void onError(String p, Throwable throwable) {\r
286                                         GWT.log("Path:"+p, throwable);\r
287                                 }\r
288                         };\r
289                         DeferredCommand.addCommand(gu);\r
290                 }\r
291 \r
292         }\r
293 \r
294         /**\r
295          * Retrieve the current.\r
296          *\r
297          * @return the current\r
298          */\r
299         TreeItem getCurrent() {\r
300                 return current;\r
301         }\r
302 \r
303         /**\r
304          * Modify the current.\r
305          *\r
306          * @param newCurrent the current to set\r
307          */\r
308         void setCurrent(final TreeItem newCurrent) {\r
309                 current = newCurrent;\r
310         }\r
311 \r
312         /**\r
313          * Modify the changed.\r
314          *\r
315          * @param newChanged the changed to set\r
316          */\r
317         private void setChanged(final TreeItem newChanged) {\r
318                 changed = newChanged;\r
319         }\r
320 \r
321         /**\r
322          * Retrieve the previous.\r
323          *\r
324          * @return the previous\r
325          */\r
326         private TreeItem getPrevious() {\r
327                 return previous;\r
328         }\r
329 \r
330         /**\r
331          * Modify the previous.\r
332          *\r
333          * @param newPrevious the previous to set\r
334          */\r
335         private void setPrevious(final TreeItem newPrevious) {\r
336                 previous = newPrevious;\r
337         }\r
338 \r
339         @Override\r
340         public void setVisible(final boolean visible) {\r
341                 super.setVisible(visible);\r
342                 if (visible)\r
343                         updateGroups();\r
344         }\r
345 \r
346         @Override\r
347         public void onSelection(SelectionEvent event) {\r
348                 final TreeItem item = (TreeItem)event.getSelectedItem();\r
349                 onSelection(item);\r
350 \r
351         }\r
352 \r
353         private void onSelection(TreeItem item){\r
354                 final Object selected = item.getUserObject();\r
355                 // Preserve the previously selected item, so that the current's\r
356                 // onClick() method gets a chance to find it.\r
357                 if (getPrevious() != null)\r
358                         getPrevious().getWidget().removeStyleName("gss-SelectedRow");\r
359                 setCurrent(item);\r
360                 getCurrent().getWidget().addStyleName("gss-SelectedRow");\r
361                 setPrevious(getCurrent());\r
362                 GSS.get().setCurrentSelection(selected);\r
363                 //cache the latest top level node (group) for selecting and expanding on refresh\r
364                 if (item.getParentItem() == null)\r
365                         selectedGroup = item.getText();\r
366                 else\r
367                         selectedGroup = item.getParentItem().getText();\r
368         }\r
369 \r
370         @Override\r
371         public void onOpen(OpenEvent event) {\r
372                 final TreeItem item = (TreeItem) event.getTarget();\r
373                 setChanged(item);\r
374                 updateUsers(item);\r
375 \r
376         }\r
377 }\r