show popup for FolderResource
[pithos] / src / gr / ebs / gss / client / CellTreeView.java
1 /*
2  * Copyright 2011 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.rest.GetCommand;
22 import gr.ebs.gss.client.rest.MultipleGetCommand;
23 import gr.ebs.gss.client.rest.RestException;
24 import gr.ebs.gss.client.rest.resource.FolderResource;
25 import gr.ebs.gss.client.rest.resource.OthersResource;
26 import gr.ebs.gss.client.rest.resource.RestResource;
27 import gr.ebs.gss.client.rest.resource.SharedResource;
28 import gr.ebs.gss.client.rest.resource.TrashResource;
29 import gr.ebs.gss.client.rest.resource.UserResource;
30
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.List;
34
35 import com.google.gwt.cell.client.AbstractCell;
36 import com.google.gwt.cell.client.Cell;
37 import com.google.gwt.cell.client.ValueUpdater;
38 import com.google.gwt.core.client.GWT;
39 import com.google.gwt.event.logical.shared.OpenEvent;
40 import com.google.gwt.resources.client.ClientBundle;
41 import com.google.gwt.resources.client.ImageResource;
42 import com.google.gwt.resources.client.ImageResource.ImageOptions;
43 import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
44 import com.google.gwt.user.cellview.client.CellTree;
45 import com.google.gwt.user.cellview.client.TreeNode;
46 import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
47 import com.google.gwt.user.client.DeferredCommand;
48 import com.google.gwt.user.client.Event;
49 import com.google.gwt.user.client.IncrementalCommand;
50 import com.google.gwt.user.client.ui.AbstractImagePrototype;
51 import com.google.gwt.user.client.ui.Composite;
52 import com.google.gwt.user.client.ui.Tree;
53 import com.google.gwt.user.client.ui.TreeItem;
54 import com.google.gwt.view.client.AbstractDataProvider;
55 import com.google.gwt.view.client.AsyncDataProvider;
56 import com.google.gwt.view.client.HasData;
57 import com.google.gwt.view.client.ListDataProvider;
58 import com.google.gwt.view.client.Range;
59 import com.google.gwt.view.client.SelectionChangeEvent;
60 import com.google.gwt.view.client.SingleSelectionModel;
61 import com.google.gwt.view.client.TreeViewModel;
62 import com.google.gwt.view.client.SelectionChangeEvent.Handler;
63 import com.google.gwt.view.client.TreeViewModel.DefaultNodeInfo;
64 import com.google.gwt.view.client.TreeViewModel.NodeInfo;
65
66
67 /**
68  * @author kman
69  *
70  */
71 public class CellTreeView extends Composite{
72         public static final boolean DONE = false;
73         Images images;
74         private final ListDataProvider<RestResource> rootNodes = new ListDataProvider<RestResource>();
75         SingleSelectionModel<RestResource> selectionModel = new SingleSelectionModel<RestResource>();
76         FolderContextMenu menu;
77         
78         
79         FolderResource myFolders=null;
80         TrashResource trash = null;
81         SharedResource myshared = null;
82         OthersResource others = null;
83         
84         TreeViewModel model = new CustomTreeModel();
85         
86         public interface Images extends ClientBundle,Tree.Resources, FolderContextMenu.Images {
87
88         @Source("gr/ebs/gss/resources/folder_home.png")
89         ImageResource home();
90
91         @Source("gr/ebs/gss/resources/folder_yellow.png")
92         ImageResource folderYellow();
93
94         @Source("gr/ebs/gss/resources/mimetypes/document.png")
95         ImageResource document();
96
97         @Source("gr/ebs/gss/resources/internet.png")
98         ImageResource othersShared();
99
100         @Source("gr/ebs/gss/resources/edit_user.png")
101         ImageResource myShared();
102
103         @Source("gr/ebs/gss/resources/folder_user.png")
104         ImageResource sharedFolder();
105
106         @Source("gr/ebs/gss/resources/trashcan_empty.png")
107         ImageResource trash();
108         }
109         final CellTree tree;
110         /*public interface BasicResources extends CellTree.BasicResources{
111                 @ImageOptions(flipRtl = true)
112             @Source("cellTreeLoadingBasic.gif")
113             ImageResource cellTreeLoading();
114                 
115                 @Source({"GssCellTreeBasic.css"})
116             CellTree.Style cellTreeStyle();
117         }*/
118         public interface BasicResources extends CellTree.Resources {
119
120             @ImageOptions(flipRtl = true)
121             @Source("cellTreeClosedItem.gif")
122             ImageResource cellTreeClosedItem();
123
124             @ImageOptions(flipRtl = true)
125             @Source("cellTreeLoadingBasic.gif")
126             ImageResource cellTreeLoading();
127
128             @ImageOptions(flipRtl = true)
129             @Source("cellTreeOpenItem.gif")
130             ImageResource cellTreeOpenItem();
131
132             //@Source({CellTree.Style.DEFAULT_CSS,"GssCellTreeBasic.css"})
133             @Source({"GssCellTreeBasic.css"})
134             CellTree.Style cellTreeStyle();
135           }
136         /**
137          * 
138          */
139         public CellTreeView(final Images _images) {
140                 images = _images;
141                 
142
143             /*
144              * Create the tree using the model. We use <code>null</code> as the default
145              * value of the root node. The default value will be passed to
146              * CustomTreeModel#getNodeInfo();
147              */
148                 CellTree.Resources res = GWT.create(BasicResources.class);
149             tree = new CellTree(model,null, res){
150                 @Override
151                 public void onBrowserEvent(Event event) {
152                         // TODO Auto-generated method stub
153                         super.onBrowserEvent(event);
154                 }
155             };
156             tree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
157             Handler selectionHandler = new SelectionChangeEvent.Handler() { 
158             @Override 
159             public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
160                 NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(selectionModel.getSelectedObject());
161                 
162                 //GWT.log("SLECTED NODE INFO:"+nodeInfo+"   "+tree.getRootTreeNode().getChildValue(1));
163                 //((DefaultNodeInfo<RestResource>)nodeInfo).getValueUpdater().update(selectionModel.getSelectedObject());
164                 //if(nodeInfo.getProvidesKey() instanceof FolderDataProvider)
165                         //((FolderDataProvider)nodeInfo.getProvidesKey()).onRangeChanged(null);
166                 if(nodeInfo.getValueUpdater()==null)
167                         GWT.log("VALUE UPDATER IS NULL");
168                 else
169                         nodeInfo.getValueUpdater().update(selectionModel.getSelectedObject());
170                 GSS.get().setCurrentSelection(selectionModel.getSelectedObject());
171                 GSS.get().showFileList(true);
172                 //tree.fireEvent(new OpenEvent<RestResource>(selectionModel.getSelectedObject()));
173                 
174             }
175         };
176         //OpenEvent<RestResource>.fire(tree, selectionModel.getSelectedObject());
177         selectionModel.addSelectionChangeHandler(selectionHandler);
178             sinkEvents(Event.ONCONTEXTMENU);
179                 sinkEvents(Event.ONMOUSEUP);
180             initWidget(tree);
181             DeferredCommand.addCommand(new IncrementalCommand() {
182
183                         @Override
184                         public boolean execute() {
185                                 return fetchRootFolders();
186                         }
187                 });
188         }
189         
190         public void updateNode(RestResource resource){
191                 NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(resource);
192         if(nodeInfo!=null){
193                 if(nodeInfo.getValueUpdater()==null)
194                         GWT.log("VALUE UPDATER IS NULL");
195                 else
196                         nodeInfo.getValueUpdater().update(resource);
197         }
198         }
199         
200         protected void showPopup(final int x, final int y) {
201                 if (selectionModel.getSelectedObject() == null)
202                         return;
203                 if (menu != null)
204                         menu.hide();
205                 menu = new FolderContextMenu(images);
206                 menu.setPopupPosition(x, y);
207                 menu.show();
208         }
209         private boolean init=false;
210         public boolean fetchRootFolders() {
211                 UserResource userResource = GSS.get().getCurrentUserResource();
212                 if (userResource == null)
213                         return !DONE;
214                 if(!init){
215                         final String path = userResource.getFilesPath();
216                         GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, null) {
217         
218                                 @Override
219                                 public void onComplete() {
220                                         myFolders = getResult();
221                                         //rootNodes.setList(Arrays.asList((RestResource)rootResource));
222                                         //tree.getRootTreeNode().setChildOpen(0, true);
223                                 }
224         
225                                 @Override
226                                 public void onError(Throwable t) {
227                                         GWT.log("Error fetching root folder", t);
228                                         GSS.get().displayError("Unable to fetch root folder");
229                                 }
230         
231                         };
232                         DeferredCommand.addCommand(gf);
233                         DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
234                                 @Override
235                                 public void onComplete() {
236                                         trash = getResult();
237                                 }
238
239                                 @Override
240                                 public void onError(Throwable t) {
241                                         if(t instanceof RestException){
242                                                 int statusCode = ((RestException)t).getHttpStatusCode();
243                                                 // On IE status code 1223 may be returned instead of 204.
244                                                 if(statusCode == 204 || statusCode == 1223){
245                                                         trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
246                                         }
247                                         else{
248                                                 GWT.log("", t);
249                                                 GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
250                                                 trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
251                                         }
252                                 }
253                         }
254                         });
255                         GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, userResource.getSharedPath(), null) {
256
257                                 @Override
258                                 public void onComplete() {
259                                         myshared=getResult();
260                                 }
261
262                                 @Override
263                                 public void onError(Throwable t) {
264                                         GWT.log("Error fetching Shared Root folder", t);
265                                         GSS.get().displayError("Unable to fetch Shared Root folder");
266                                 }
267                         };
268                         DeferredCommand.addCommand(gs);
269                         GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
270                                                 userResource.getOthersPath(), null) {
271
272                                 @Override
273                                 public void onComplete() {
274                                         others = getResult();
275                                         GSS.get().removeGlassPanel();
276                                 }
277
278                                 @Override
279                                 public void onError(Throwable t) {
280                                         GWT.log("Error fetching Others Root folder", t);
281                                         GSS.get().displayError("Unable to fetch Others Root folder");
282                                 }
283                         };
284                         DeferredCommand.addCommand(go);
285                 }
286                 if(myFolders==null||trash==null||myshared==null||others==null)
287                         return !DONE;
288                 rootNodes.setList(Arrays.asList((RestResource)myFolders,(RestResource)trash,(RestResource)myshared,(RestResource)others));
289                 tree.getRootTreeNode().setChildOpen(0, true);
290                 return DONE;
291         }
292
293         public Images getImages() {
294                 return images;
295         }
296         
297         
298         class CustomTreeModel implements TreeViewModel{
299                 private final Cell<RestResource> departmentCell = new AbstractCell<RestResource>("contextmenu"){
300                         
301                         @Override
302                         public void render(com.google.gwt.cell.client.Cell.Context arg0, RestResource arg1, SafeHtmlBuilder arg2) {
303                                 String html=null;
304                                 String name=null;
305                                 if(arg1 instanceof FolderResource){
306                                         FolderResource res = (FolderResource) arg1;
307                                         if(res.isShared())
308                                                 html = AbstractImagePrototype.create(images.sharedFolder()).getHTML();
309                                         else if(res.getParentName()==null){
310                                                 html = AbstractImagePrototype.create(images.home()).getHTML();
311                                         }
312                                         else
313                                                 html = AbstractImagePrototype.create(images.folderYellow()).getHTML();
314                                         name = res.getName();
315                                         
316                                 }
317                                 if(arg1 instanceof TrashResource){
318                                         html = AbstractImagePrototype.create(images.trash()).getHTML();
319                                         name="Trash";
320                                 }
321                                 if(arg1 instanceof SharedResource){
322                                         html = AbstractImagePrototype.create(images.myShared()).getHTML();
323                                         name="My Shared";
324                                 }
325                                 if(arg1 instanceof OthersResource){
326                                         html = AbstractImagePrototype.create(images.othersShared()).getHTML();
327                                         name = "Other's Shared";
328                                 }
329                                 arg2.appendHtmlConstant(html);
330                                 arg2.appendHtmlConstant("<span class='papala'>");
331                                 arg2.appendEscaped(name);
332                                 arg2.appendHtmlConstant("</span>");
333                         }
334                         
335                         public void onBrowserEvent(Cell.Context context, com.google.gwt.dom.client.Element parent, RestResource value, com.google.gwt.dom.client.NativeEvent event, com.google.gwt.cell.client.ValueUpdater<RestResource> valueUpdater) {
336                                 GWT.log("-->"+event.getType());
337                                 if(event.getType().equals("contextmenu")){
338                                         selectionModel.setSelected(value, true);
339                                         showPopup(event.getClientX(), event.getClientY());
340                                 }
341                         };
342                         
343                 };
344                 
345                 
346                 @Override
347                 public <T> NodeInfo<?> getNodeInfo(T value) {
348                         
349                         if(value==null){
350                                 return new DefaultNodeInfo<RestResource>(rootNodes, departmentCell,
351                                             selectionModel, null);
352                         }
353                         else if (value instanceof FolderResource) {
354                         // Second level.
355                                 FolderDataProvider dataProvider = new FolderDataProvider(
356                             ((FolderResource) value).getUri());
357                         return new DefaultNodeInfo<RestResource>(dataProvider, departmentCell,
358                             selectionModel, new ResourceValueUpdater());
359                         }
360                         else if (value instanceof SharedResource) {
361                         // Second level.
362                                 FolderDataProvider dataProvider = new FolderDataProvider(
363                             ((SharedResource) value).getUri());
364                         return new DefaultNodeInfo<RestResource>(dataProvider, departmentCell,
365                             selectionModel, null);
366                         }
367                         // TODO Auto-generated method stub
368                         return null;
369                 }
370
371                 @Override
372                 public boolean isLeaf(Object value) {
373                         if(value instanceof FolderResource)
374                                 return ((FolderResource)value).getFolders().size()==0;
375                         if(value instanceof TrashResource)
376                                 return ((TrashResource)value).getFolders().size()==0;
377                         return false;
378                 }
379                 
380         }
381         class ResourceValueUpdater implements  ValueUpdater<RestResource>{
382
383                 @Override
384                 public void update(final RestResource value) {
385                         if(value instanceof FolderResource){
386                                 GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, value.getUri(), null) {
387
388                                         @Override
389                                         public void onComplete() {
390                                                 FolderResource rootResource = getResult();
391                                                 ((FolderResource)value).setFiles(rootResource.getFiles());
392                                                 if(getSelection().getUri().equals(value.getUri()))
393                                                         selectionModel.setSelected(value, true);
394                                                 GSS.get().onResourceUpdate(value);
395                                         }
396         
397                                         @Override
398                                         public void onError(Throwable t) {
399                                                 GWT.log("Error fetching root folder", t);
400                                                 GSS.get().displayError("Unable to fetch root folder");
401                                         }
402         
403                                 };
404                                 DeferredCommand.addCommand(gf);
405                         }
406                         
407                 }
408                 
409         }
410         class FolderDataProvider extends AsyncDataProvider<RestResource>{
411                 private final String department;
412
413                   public FolderDataProvider(String department) {
414                     super(null);
415                     this.department = department;
416                   }
417
418                   @Override
419                   protected void onRangeChanged(final HasData<RestResource> view) {
420                     GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, department, null) {
421
422                                 @Override
423                                 public void onComplete() {
424                                         FolderResource rootResource = getResult();
425                                         MultipleGetCommand<FolderResource> gf2 = new MultipleGetCommand<FolderResource>(FolderResource.class,
426                                                                 rootResource.getSubfolderPaths().toArray(new String[] {}), null) {
427
428                                                 @Override
429                                                 public void onComplete() {
430                                                         List<RestResource> res = new ArrayList<RestResource>();
431                                                         res.addAll(getResult());
432                                                         updateRowCount(res.size(), true);
433                                                         updateRowData(0,res);
434                                                 }
435
436                                                 @Override
437                                                 public void onError(Throwable t) {
438                                                         GSS.get().displayError("Unable to fetch subfolders");
439                                                         GWT.log("Unable to fetch subfolders", t);
440                                                 }
441
442                                                 @Override
443                                                 public void onError(String p, Throwable throwable) {
444                                                         GWT.log("Path:"+p, throwable);
445                                                 }
446
447                                         };
448                                         DeferredCommand.addCommand(gf2);
449                                         
450                                 }
451
452                                 @Override
453                                 public void onError(Throwable t) {
454                                         GWT.log("Error fetching root folder", t);
455                                         GSS.get().displayError("Unable to fetch root folder");
456                                 }
457
458                         };
459                         DeferredCommand.addCommand(gf);
460                     
461                         
462                   }
463                 
464         }
465         
466         
467         public RestResource getSelection(){
468                 return selectionModel.getSelectedObject();
469         }
470         
471         
472         /**
473          * Retrieve the myFolders.
474          *
475          * @return the myFolders
476          */
477         public FolderResource getMyFolders() {
478                 return myFolders;
479         }
480         
481         
482         /**
483          * Retrieve the myshared.
484          *
485          * @return the myshared
486          */
487         public SharedResource getMyshared() {
488                 return myshared;
489         }
490         
491         
492         /**
493          * Retrieve the trash.
494          *
495          * @return the trash
496          */
497         public TrashResource getTrash() {
498                 return trash;
499         }
500         
501         
502         /**
503          * Retrieve the others.
504          *
505          * @return the others
506          */
507         public OthersResource getOthers() {
508                 return others;
509         }
510         
511         
512         /**
513          * Retrieve the model.
514          *
515          * @return the model
516          */
517         public TreeViewModel getModel() {
518                 return model;
519         }
520         /*
521         private TreeNode getUserItem(TreeNode parent, RestResource folder) {
522                 if(parent==null)
523                         parent = tree.getRootTreeNode();
524                 TreeNode tmp = null;
525                 if (parent.getValue() instanceof RestResource &&
526                                         (parent.getValue().equals(folder) ||
527                                         ((FolderResource) parent.getValue()).getUri().equals(folder.getUri())))
528                         return parent;
529                 for (int i = 0; i < parent.getChildCount(); i++) {
530                         boolean op = parent.isChildOpen(i);
531                         TreeNode child = parent.setChildOpen(index, open, fireEvents)(i);
532                         if (child.getUserObject() instanceof FolderResource) {
533                                 FolderResource dto = (FolderResource) child.getUserObject();
534                                 if (dto.equals(folder) || dto.getUri().equals(folder.getUri()))
535                                         return child;
536                         }
537                         tmp = getUserItem(child, folder);
538                         if (tmp != null)
539                                 return tmp;
540                 }
541                 return null;
542         }*/
543 }