b3f069e7819c98697de6b7895883faddd3f5c9ba
[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                         //GWT.log(event.getType());
155                 }
156             };
157             tree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
158             Handler selectionHandler = new SelectionChangeEvent.Handler() { 
159             @Override 
160             public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
161                 NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(selectionModel.getSelectedObject());
162                 
163                 //GWT.log("SLECTED NODE INFO:"+nodeInfo+"   "+tree.getRootTreeNode().getChildValue(1));
164                 //((DefaultNodeInfo<RestResource>)nodeInfo).getValueUpdater().update(selectionModel.getSelectedObject());
165                 //if(nodeInfo.getProvidesKey() instanceof FolderDataProvider)
166                         //((FolderDataProvider)nodeInfo.getProvidesKey()).onRangeChanged(null);
167                 if(nodeInfo.getValueUpdater()==null)
168                         GWT.log("VALUE UPDATER IS NULL");
169                 else
170                         nodeInfo.getValueUpdater().update(selectionModel.getSelectedObject());
171                 GSS.get().setCurrentSelection(selectionModel.getSelectedObject());
172                 GSS.get().showFileList(true);
173                 //tree.fireEvent(new OpenEvent<RestResource>(selectionModel.getSelectedObject()));
174                 
175             }
176         };
177         //OpenEvent<RestResource>.fire(tree, selectionModel.getSelectedObject());
178         selectionModel.addSelectionChangeHandler(selectionHandler);
179             sinkEvents(Event.ONCONTEXTMENU);
180                 sinkEvents(Event.ONMOUSEUP);
181             initWidget(tree);
182             DeferredCommand.addCommand(new IncrementalCommand() {
183
184                         @Override
185                         public boolean execute() {
186                                 return fetchRootFolders();
187                         }
188                 });
189         }
190         
191         public void updateNode(RestResource resource){
192                 NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(resource);
193         if(nodeInfo!=null){
194                 if(nodeInfo.getValueUpdater()==null)
195                         GWT.log("VALUE UPDATER IS NULL");
196                 else
197                         nodeInfo.getValueUpdater().update(resource);
198         }
199         }
200         
201         protected void showPopup(final int x, final int y) {
202                 if (selectionModel.getSelectedObject() == null)
203                         return;
204                 if (menu != null)
205                         menu.hide();
206                 menu = new FolderContextMenu(images);
207                 menu.setPopupPosition(x, y);
208                 menu.show();
209         }
210         private boolean init=false;
211         public boolean fetchRootFolders() {
212                 UserResource userResource = GSS.get().getCurrentUserResource();
213                 if (userResource == null)
214                         return !DONE;
215                 if(!init){
216                         final String path = userResource.getFilesPath();
217                         GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, null) {
218         
219                                 @Override
220                                 public void onComplete() {
221                                         myFolders = getResult();
222                                         //rootNodes.setList(Arrays.asList((RestResource)rootResource));
223                                         //tree.getRootTreeNode().setChildOpen(0, true);
224                                 }
225         
226                                 @Override
227                                 public void onError(Throwable t) {
228                                         GWT.log("Error fetching root folder", t);
229                                         GSS.get().displayError("Unable to fetch root folder");
230                                 }
231         
232                         };
233                         DeferredCommand.addCommand(gf);
234                         DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
235                                 @Override
236                                 public void onComplete() {
237                                         trash = getResult();
238                                 }
239
240                                 @Override
241                                 public void onError(Throwable t) {
242                                         if(t instanceof RestException){
243                                                 int statusCode = ((RestException)t).getHttpStatusCode();
244                                                 // On IE status code 1223 may be returned instead of 204.
245                                                 if(statusCode == 204 || statusCode == 1223){
246                                                         trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
247                                         }
248                                         else{
249                                                 GWT.log("", t);
250                                                 GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
251                                                 trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
252                                         }
253                                 }
254                         }
255                         });
256                         GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, userResource.getSharedPath(), null) {
257
258                                 @Override
259                                 public void onComplete() {
260                                         myshared=getResult();
261                                 }
262
263                                 @Override
264                                 public void onError(Throwable t) {
265                                         GWT.log("Error fetching Shared Root folder", t);
266                                         GSS.get().displayError("Unable to fetch Shared Root folder");
267                                 }
268                         };
269                         DeferredCommand.addCommand(gs);
270                         GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
271                                                 userResource.getOthersPath(), null) {
272
273                                 @Override
274                                 public void onComplete() {
275                                         others = getResult();
276                                         GSS.get().removeGlassPanel();
277                                 }
278
279                                 @Override
280                                 public void onError(Throwable t) {
281                                         GWT.log("Error fetching Others Root folder", t);
282                                         GSS.get().displayError("Unable to fetch Others Root folder");
283                                 }
284                         };
285                         DeferredCommand.addCommand(go);
286                 }
287                 if(myFolders==null||trash==null||myshared==null||others==null)
288                         return !DONE;
289                 rootNodes.setList(Arrays.asList((RestResource)myFolders,(RestResource)trash,(RestResource)myshared,(RestResource)others));
290                 tree.getRootTreeNode().setChildOpen(0, true);
291                 return DONE;
292         }
293
294         public Images getImages() {
295                 return images;
296         }
297         
298         
299         class CustomTreeModel implements TreeViewModel{
300                 private final Cell<RestResource> departmentCell = new AbstractCell<RestResource>("contextmenu"){
301                         
302                         @Override
303                         public void render(com.google.gwt.cell.client.Cell.Context arg0, RestResource arg1, SafeHtmlBuilder arg2) {
304                                 String html=null;
305                                 String name=null;
306                                 if(arg1 instanceof FolderResource){
307                                         FolderResource res = (FolderResource) arg1;
308                                         if(res.isShared())
309                                                 html = AbstractImagePrototype.create(images.sharedFolder()).getHTML();
310                                         else if(res.getParentName()==null){
311                                                 html = AbstractImagePrototype.create(images.home()).getHTML();
312                                         }
313                                         else
314                                                 html = AbstractImagePrototype.create(images.folderYellow()).getHTML();
315                                         name = res.getName();
316                                         
317                                 }
318                                 if(arg1 instanceof TrashResource){
319                                         html = AbstractImagePrototype.create(images.trash()).getHTML();
320                                         name="Trash";
321                                 }
322                                 if(arg1 instanceof SharedResource){
323                                         html = AbstractImagePrototype.create(images.myShared()).getHTML();
324                                         name="My Shared";
325                                 }
326                                 if(arg1 instanceof OthersResource){
327                                         html = AbstractImagePrototype.create(images.othersShared()).getHTML();
328                                         name = "Other's Shared";
329                                 }
330                                 arg2.appendHtmlConstant(html);
331                                 arg2.appendHtmlConstant("<span class='papala'>");
332                                 arg2.appendEscaped(name);
333                                 arg2.appendHtmlConstant("</span>");
334                         }
335                         
336                         public void onBrowserEvent(Cell.Context context, com.google.gwt.dom.client.Element parent, FolderResource value, com.google.gwt.dom.client.NativeEvent event, com.google.gwt.cell.client.ValueUpdater<FolderResource> valueUpdater) {
337                                 GWT.log("-->"+event.getType());
338                                 if(event.getType().equals("contextmenu")){
339                                         selectionModel.setSelected(value, true);
340                                         showPopup(event.getClientX(), event.getClientY());
341                                 }
342                         };
343                         
344                 };
345                 
346                 
347                 @Override
348                 public <T> NodeInfo<?> getNodeInfo(T value) {
349                         
350                         if(value==null){
351                                 return new DefaultNodeInfo<RestResource>(rootNodes, departmentCell,
352                                             selectionModel, null);
353                         }
354                         else if (value instanceof FolderResource) {
355                         // Second level.
356                                 FolderDataProvider dataProvider = new FolderDataProvider(
357                             ((FolderResource) value).getUri());
358                         return new DefaultNodeInfo<RestResource>(dataProvider, departmentCell,
359                             selectionModel, new ResourceValueUpdater());
360                         }
361                         else if (value instanceof SharedResource) {
362                         // Second level.
363                                 FolderDataProvider dataProvider = new FolderDataProvider(
364                             ((SharedResource) value).getUri());
365                         return new DefaultNodeInfo<RestResource>(dataProvider, departmentCell,
366                             selectionModel, null);
367                         }
368                         // TODO Auto-generated method stub
369                         return null;
370                 }
371
372                 @Override
373                 public boolean isLeaf(Object value) {
374                         if(value instanceof FolderResource)
375                                 return ((FolderResource)value).getFolders().size()==0;
376                         if(value instanceof TrashResource)
377                                 return ((TrashResource)value).getFolders().size()==0;
378                         return false;
379                 }
380                 
381         }
382         class ResourceValueUpdater implements  ValueUpdater<RestResource>{
383
384                 @Override
385                 public void update(final RestResource value) {
386                         if(value instanceof FolderResource){
387                                 GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, value.getUri(), null) {
388
389                                         @Override
390                                         public void onComplete() {
391                                                 FolderResource rootResource = getResult();
392                                                 ((FolderResource)value).setFiles(rootResource.getFiles());
393                                                 if(getSelection().getUri().equals(value.getUri()))
394                                                         selectionModel.setSelected(value, true);
395                                                 GSS.get().onResourceUpdate(value);
396                                         }
397         
398                                         @Override
399                                         public void onError(Throwable t) {
400                                                 GWT.log("Error fetching root folder", t);
401                                                 GSS.get().displayError("Unable to fetch root folder");
402                                         }
403         
404                                 };
405                                 DeferredCommand.addCommand(gf);
406                         }
407                         
408                 }
409                 
410         }
411         class FolderDataProvider extends AsyncDataProvider<RestResource>{
412                 private final String department;
413
414                   public FolderDataProvider(String department) {
415                     super(null);
416                     this.department = department;
417                   }
418
419                   @Override
420                   protected void onRangeChanged(final HasData<RestResource> view) {
421                     GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, department, null) {
422
423                                 @Override
424                                 public void onComplete() {
425                                         FolderResource rootResource = getResult();
426                                         MultipleGetCommand<FolderResource> gf2 = new MultipleGetCommand<FolderResource>(FolderResource.class,
427                                                                 rootResource.getSubfolderPaths().toArray(new String[] {}), null) {
428
429                                                 @Override
430                                                 public void onComplete() {
431                                                         List<RestResource> res = new ArrayList<RestResource>();
432                                                         res.addAll(getResult());
433                                                         updateRowCount(res.size(), true);
434                                                         updateRowData(0,res);
435                                                 }
436
437                                                 @Override
438                                                 public void onError(Throwable t) {
439                                                         GSS.get().displayError("Unable to fetch subfolders");
440                                                         GWT.log("Unable to fetch subfolders", t);
441                                                 }
442
443                                                 @Override
444                                                 public void onError(String p, Throwable throwable) {
445                                                         GWT.log("Path:"+p, throwable);
446                                                 }
447
448                                         };
449                                         DeferredCommand.addCommand(gf2);
450                                         
451                                 }
452
453                                 @Override
454                                 public void onError(Throwable t) {
455                                         GWT.log("Error fetching root folder", t);
456                                         GSS.get().displayError("Unable to fetch root folder");
457                                 }
458
459                         };
460                         DeferredCommand.addCommand(gf);
461                     
462                         
463                   }
464                 
465         }
466         
467         
468         public RestResource getSelection(){
469                 return selectionModel.getSelectedObject();
470         }
471         
472         
473         /**
474          * Retrieve the myFolders.
475          *
476          * @return the myFolders
477          */
478         public FolderResource getMyFolders() {
479                 return myFolders;
480         }
481         
482         
483         /**
484          * Retrieve the myshared.
485          *
486          * @return the myshared
487          */
488         public SharedResource getMyshared() {
489                 return myshared;
490         }
491         
492         
493         /**
494          * Retrieve the trash.
495          *
496          * @return the trash
497          */
498         public TrashResource getTrash() {
499                 return trash;
500         }
501         
502         
503         /**
504          * Retrieve the others.
505          *
506          * @return the others
507          */
508         public OthersResource getOthers() {
509                 return others;
510         }
511         
512         
513         /**
514          * Retrieve the model.
515          *
516          * @return the model
517          */
518         public TreeViewModel getModel() {
519                 return model;
520         }
521         /*
522         private TreeNode getUserItem(TreeNode parent, RestResource folder) {
523                 if(parent==null)
524                         parent = tree.getRootTreeNode();
525                 TreeNode tmp = null;
526                 if (parent.getValue() instanceof RestResource &&
527                                         (parent.getValue().equals(folder) ||
528                                         ((FolderResource) parent.getValue()).getUri().equals(folder.getUri())))
529                         return parent;
530                 for (int i = 0; i < parent.getChildCount(); i++) {
531                         boolean op = parent.isChildOpen(i);
532                         TreeNode child = parent.setChildOpen(index, open, fireEvents)(i);
533                         if (child.getUserObject() instanceof FolderResource) {
534                                 FolderResource dto = (FolderResource) child.getUserObject();
535                                 if (dto.equals(folder) || dto.getUri().equals(folder.getUri()))
536                                         return child;
537                         }
538                         tmp = getUserItem(child, folder);
539                         if (tmp != null)
540                                 return tmp;
541                 }
542                 return null;
543         }*/
544 }