90c8ca0475b5c5dec216c46f1da784e9a1bdb25e
[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.CellTreeViewModel.MyFolderDataProvider;
22 import gr.ebs.gss.client.rest.GetCommand;
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.MyFolderResource;
26 import gr.ebs.gss.client.rest.resource.OtherUserResource;
27 import gr.ebs.gss.client.rest.resource.OthersFolderResource;
28 import gr.ebs.gss.client.rest.resource.OthersResource;
29 import gr.ebs.gss.client.rest.resource.RestResource;
30 import gr.ebs.gss.client.rest.resource.RestResourceWrapper;
31 import gr.ebs.gss.client.rest.resource.SharedResource;
32 import gr.ebs.gss.client.rest.resource.TrashFolderResource;
33 import gr.ebs.gss.client.rest.resource.TrashResource;
34 import gr.ebs.gss.client.rest.resource.UserResource;
35 import gwtquery.plugins.draggable.client.DragAndDropManager;
36 import gwtquery.plugins.droppable.client.events.DragAndDropContext;
37 import gwtquery.plugins.droppable.client.gwt.DragAndDropCellTree;
38
39 import java.util.Arrays;
40
41 import com.google.gwt.core.client.GWT;
42 import com.google.gwt.query.client.plugins.GQueryUi;
43 import com.google.gwt.resources.client.ClientBundle;
44 import com.google.gwt.resources.client.ImageResource;
45 import com.google.gwt.resources.client.ImageResource.ImageOptions;
46 import com.google.gwt.user.cellview.client.CellTree;
47 import com.google.gwt.user.cellview.client.TreeNode;
48 import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
49 import com.google.gwt.user.client.DeferredCommand;
50 import com.google.gwt.user.client.Event;
51 import com.google.gwt.user.client.IncrementalCommand;
52 import com.google.gwt.user.client.Window;
53 import com.google.gwt.user.client.ui.Composite;
54 import com.google.gwt.user.client.ui.Tree;
55 import com.google.gwt.view.client.ProvidesKey;
56 import com.google.gwt.view.client.SelectionChangeEvent;
57 import com.google.gwt.view.client.SingleSelectionModel;
58 import com.google.gwt.view.client.TreeViewModel;
59 import com.google.gwt.view.client.SelectionChangeEvent.Handler;
60 import com.google.gwt.view.client.TreeViewModel.NodeInfo;
61
62
63 /**
64  * @author kman
65  *
66  */
67 public class CellTreeView extends Composite{
68         public static final boolean DONE = false;
69         Images images;
70         
71         SingleSelectionModel<RestResource> selectionModel = new SingleSelectionModel<RestResource>(new ProvidesKey<RestResource>() {
72
73                 @Override
74                 public Object getKey(RestResource item) {
75                         return item.getClass().getName()+":"+item.getUri();
76                 }});
77         FolderContextMenu menu;
78         
79         
80         MyFolderResource myFolders=null;
81         TrashResource trash = null;
82         SharedResource myshared = null;
83         OthersResource others = null;
84         
85         CellTreeViewModel model;
86         CellTreeViewUtils utils;
87         
88         public interface Images extends ClientBundle,Tree.Resources, FolderContextMenu.Images {
89
90         @Source("gr/ebs/gss/resources/folder_home.png")
91         ImageResource home();
92
93         @Source("gr/ebs/gss/resources/folder_yellow.png")
94         ImageResource folderYellow();
95
96         @Source("gr/ebs/gss/resources/mimetypes/document.png")
97         ImageResource document();
98
99         @Source("gr/ebs/gss/resources/internet.png")
100         ImageResource othersShared();
101
102         @Source("gr/ebs/gss/resources/edit_user.png")
103         ImageResource myShared();
104
105         @Source("gr/ebs/gss/resources/folder_user.png")
106         ImageResource sharedFolder();
107
108         @Source("gr/ebs/gss/resources/trashcan_empty.png")
109         ImageResource trash();
110         }
111         DragAndDropCellTree tree;
112         /*public interface BasicResources extends CellTree.BasicResources{
113                 @ImageOptions(flipRtl = true)
114             @Source("cellTreeLoadingBasic.gif")
115             ImageResource cellTreeLoading();
116                 
117                 @Source({"GssCellTreeBasic.css"})
118             CellTree.Style cellTreeStyle();
119         }*/
120         public interface BasicResources extends CellTree.Resources {
121
122             @ImageOptions(flipRtl = true)
123             @Source("cellTreeClosedItem.gif")
124             ImageResource cellTreeClosedItem();
125
126             @ImageOptions(flipRtl = true)
127             @Source("cellTreeLoadingBasic.gif")
128             ImageResource cellTreeLoading();
129
130             @ImageOptions(flipRtl = true)
131             @Source("cellTreeOpenItem.gif")
132             ImageResource cellTreeOpenItem();
133
134             //@Source({CellTree.Style.DEFAULT_CSS,"GssCellTreeBasic.css"})
135             @Source({"GssCellTreeBasic.css"})
136             CellTree.Style cellTreeStyle();
137           }
138         /**
139          * 
140          */
141         public CellTreeView(final Images _images) {
142                 images = _images;
143                 model = new CellTreeViewModel(images,selectionModel);
144             /*
145              * Create the tree using the model. We use <code>null</code> as the default
146              * value of the root node. The default value will be passed to
147              * CustomTreeModel#getNodeInfo();
148              */
149                 CellTree.Resources res = GWT.create(BasicResources.class);
150             tree = new DragAndDropCellTree(model,null, res){
151                 @Override
152                 public void onBrowserEvent(Event event) {
153                         // TODO Auto-generated method stub
154                         super.onBrowserEvent(event);
155                 }
156             };
157             utils=new CellTreeViewUtils(tree);
158             tree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
159             
160             Handler selectionHandler = new SelectionChangeEvent.Handler() { 
161             @Override 
162             public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
163                 NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(selectionModel.getSelectedObject());
164                 
165                 //GWT.log("SLECTED NODE INFO:"+nodeInfo+"   "+tree.getRootTreeNode().getChildValue(1));
166                 //((DefaultNodeInfo<RestResource>)nodeInfo).getValueUpdater().update(selectionModel.getSelectedObject());
167                 //if(nodeInfo.getProvidesKey() instanceof FolderDataProvider)
168                         //((FolderDataProvider)nodeInfo.getProvidesKey()).onRangeChanged(null);
169                 if(nodeInfo==null || nodeInfo.getValueUpdater()==null){}
170                         
171                 else
172                         nodeInfo.getValueUpdater().update(selectionModel.getSelectedObject());
173                 GSS.get().setCurrentSelection(selectionModel.getSelectedObject());
174                 GSS.get().showFileList(true);
175                 //tree.fireEvent(new OpenEvent<RestResource>(selectionModel.getSelectedObject()));
176                 
177             }
178         };
179         //OpenEvent<RestResource>.fire(tree, selectionModel.getSelectedObject());
180         selectionModel.addSelectionChangeHandler(selectionHandler);
181             sinkEvents(Event.ONCONTEXTMENU);
182                 sinkEvents(Event.ONMOUSEUP);
183             initWidget(tree);
184                 
185             DeferredCommand.addCommand(new IncrementalCommand() {
186
187                         @Override
188                         public boolean execute() {
189                                 return fetchRootFolders();
190                         }
191                 });
192         }
193         
194         public void updateNode(RestResource resource){
195                 NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(resource);
196                 
197                 if(nodeInfo!=null){
198                 if(nodeInfo.getValueUpdater()==null){}
199                 else
200                         nodeInfo.getValueUpdater().update(resource);
201         }
202         }
203         
204         public void updateNodeChildren(final RestResource resource){
205                 
206                 if(resource instanceof RestResourceWrapper){
207                         boolean updated=false;
208                         if(((RestResourceWrapper)resource).getResource().getFolders().size()==0){
209                                 if(model.getMymap().get(((RestResourceWrapper)resource).getResource().getParentURI())!=null){
210                                         model.getMymap().get(((RestResourceWrapper)resource).getResource().getParentURI()).refresh(null);
211                                         updated=true;
212                                 }
213                                 if(model.getOthersmap().get(((RestResourceWrapper)resource).getResource().getParentURI())!=null){
214                                         model.getOthersmap().get(((RestResourceWrapper)resource).getResource().getParentURI()).refresh(null);
215                                         updated=true;
216                                 }
217                                 if(model.getSharedmap().get(((RestResourceWrapper)resource).getResource().getParentURI())!=null){
218                                         model.getSharedmap().get(((RestResourceWrapper)resource).getResource().getParentURI()).refresh(null);
219                                         updated=true;
220                                 }
221                                 if(updated){
222                                         if(utils.doesSharedNodeContainsResourceIn1stLevel(resource.getUri())){
223                                                 updateMySharedNode();
224                                         }
225                                         return;
226                                 }
227                         }
228                 }
229                 
230                 utils.refreshNodeContainingResource(resource);
231                 if(utils.doesSharedNodeContainsResourceIn1stLevel(resource.getUri())){
232                         updateMySharedNode();
233                 }
234                 
235         }
236         public void updateNodeChildrenForRemove(final String resource){
237                 GWT.log("********************************");
238                 GWT.log("[UPDATENODECHILDREN]"+resource);
239                 GWT.log("********************************");
240                 boolean updated=false;
241                 TreeNode node=null;
242                 if(tree.getRootTreeNode().isChildOpen(0)){
243                         node = utils.getNodeContainingResource2(tree.getRootTreeNode().setChildOpen(0,true), resource);
244                 }
245                         GWT.log("CHECK NODE1:"+node+" "+resource);
246                         if(node==null)
247                                 if(tree.getRootTreeNode().isChildOpen(2)){
248                                         GWT.log("CHECK NODE2:"+node);
249                                         node = utils.getNodeContainingResource2(tree.getRootTreeNode().setChildOpen(2,true), resource);
250                                 }
251                         if(node==null)
252                                 if(tree.getRootTreeNode().isChildOpen(3)){
253                                         GWT.log("CHECK NODE3:"+node);
254                                         node = utils.getNodeContainingResource2(tree.getRootTreeNode().setChildOpen(3,true), resource);
255                                 }
256                         
257                         if(node != null && node.getValue() instanceof RestResourceWrapper){
258                                 GWT.log("*********************"+((RestResourceWrapper) node.getValue()).getResource().getFolders().size());
259                                 if(((RestResourceWrapper) node.getValue()).getResource().getFolders().size()==1)
260                                         updateNodeChildren(((RestResourceWrapper) node.getValue()).getResource().getParentURI());
261                                 else
262                                         updateNodeChildren(((RestResource) node.getValue()).getUri());
263                                 return;
264                                 /*GWT.log("INSIDE:"+node);
265                                 RestResourceWrapper rw = (RestResourceWrapper) node.getValue();
266                                 //if(rw.getResource().getFolders().size()==0){
267                                         if(model.getMymap().get(rw.getResource().getUri())!=null){
268                                                 model.getMymap().get(rw.getResource().getUri()).refresh(null);
269                                                 updated=true;
270                                         }
271                                         if(model.getOthersmap().get(rw.getResource().getUri())!=null){
272                                                 model.getOthersmap().get(rw.getResource().getUri()).refresh(null);
273                                                 updated=true;
274                                         }
275                                         if(model.getSharedmap().get(rw.getResource().getUri())!=null){
276                                                 model.getSharedmap().get(rw.getResource().getUri()).refresh(null);
277                                                 updated=true;
278                                         }
279                                         if(updated){
280                                                 if(doesSharedNodeContainsResourceIn1stLevel(resource)){
281                                                         updateMySharedNode();
282                                                 }
283                                                 return;
284                                         }
285                                 }
286                         //}*/
287                         
288                 }
289                         updateNodeChildren(resource);
290         }
291         public void updateNodeChildren(final String resource){
292                 
293                         
294                 GWT.log("REFRESH THE OTHER WAY");
295                 utils.refreshNodeContainingResource(resource);
296                 if(utils.doesSharedNodeContainsResourceIn1stLevel(resource)){
297                         updateMySharedNode();
298                 }
299         }
300         
301         protected void showPopup(final int x, final int y) {
302                 if (selectionModel.getSelectedObject() == null)
303                         return;
304                 if (menu != null)
305                         menu.hide();
306                 menu = new FolderContextMenu(images);
307                 menu.setPopupPosition(x, y);
308                 menu.show();
309         }
310         private boolean init=false;
311         public boolean fetchRootFolders() {
312                 UserResource userResource = GSS.get().getCurrentUserResource();
313                 if (userResource == null)
314                         return !DONE;
315                 if(!init){
316                         final String path = userResource.getFilesPath();
317                         GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, null) {
318         
319                                 @Override
320                                 public void onComplete() {
321                                         myFolders = new MyFolderResource(getResult());
322                                         //selectionModel.setSelected(myFolders, true);
323                                         //rootNodes.setList(Arrays.asList((RestResource)rootResource));
324                                         //tree.getRootTreeNode().setChildOpen(0, true);
325                                 }
326         
327                                 @Override
328                                 public void onError(Throwable t) {
329                                         GWT.log("Error fetching root folder", t);
330                                         GSS.get().displayError("Unable to fetch root folder");
331                                 }
332         
333                         };
334                         DeferredCommand.addCommand(gf);
335                         DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
336                                 @Override
337                                 public void onComplete() {
338                                         trash = getResult();
339                                 }
340
341                                 @Override
342                                 public void onError(Throwable t) {
343                                         if(t instanceof RestException){
344                                                 int statusCode = ((RestException)t).getHttpStatusCode();
345                                                 // On IE status code 1223 may be returned instead of 204.
346                                                 if(statusCode == 204 || statusCode == 1223){
347                                                         trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
348                                         }
349                                         else{
350                                                 GWT.log("", t);
351                                                 GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
352                                                 trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
353                                         }
354                                 }
355                         }
356                         });
357                         GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, userResource.getSharedPath(), null) {
358
359                                 @Override
360                                 public void onComplete() {
361                                         myshared=getResult();
362                                 }
363
364                                 @Override
365                                 public void onError(Throwable t) {
366                                         GWT.log("Error fetching Shared Root folder", t);
367                                         GSS.get().displayError("Unable to fetch Shared Root folder");
368                                 }
369                         };
370                         DeferredCommand.addCommand(gs);
371                         GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
372                                                 userResource.getOthersPath(), null) {
373
374                                 @Override
375                                 public void onComplete() {
376                                         others = getResult();
377                                         GSS.get().removeGlassPanel();
378                                 }
379
380                                 @Override
381                                 public void onError(Throwable t) {
382                                         GWT.log("Error fetching Others Root folder", t);
383                                         GSS.get().displayError("Unable to fetch Others Root folder");
384                                 }
385                         };
386                         DeferredCommand.addCommand(go);
387                 }
388                 if(myFolders==null||trash==null||myshared==null||others==null)
389                         return !DONE;
390                 model.getRootNodes().setList(Arrays.asList((RestResource)myFolders,(RestResource)trash,(RestResource)myshared,(RestResource)others));
391                 tree.getRootTreeNode().setChildOpen(0, true);
392                 selectionModel.setSelected(myFolders, true);
393                 return DONE;
394         }
395
396         public Images getImages() {
397                 return images;
398         }
399         
400         
401         public void updateTrashNode(){
402                 DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
403                         @Override
404                         public void onComplete() {
405                                 trash = getResult();
406                                 model.getRootNodes().getList().set(1, trash);
407                                 //model.getRootNodes().refresh();
408                         }
409
410                         @Override
411                         public void onError(Throwable t) {
412                                 if(t instanceof RestException){
413                                         int statusCode = ((RestException)t).getHttpStatusCode();
414                                         // On IE status code 1223 may be returned instead of 204.
415                                         if(statusCode == 204 || statusCode == 1223){
416                                                 trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
417                                                 model.getRootNodes().getList().set(1, trash);
418                                                 //model.getRootNodes().refresh();
419                                 }
420                                 else{
421                                         GWT.log("", t);
422                                         GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
423                                         trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
424                                         model.getRootNodes().getList().set(1, trash);
425                                         //model.getRootNodes().refresh();
426                                 }
427                         }
428                 }
429                 });
430         }
431         
432         public void updateRootNode(){
433                 final String path = GSS.get().getCurrentUserResource().getFilesPath();
434                 GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, null) {
435
436                         @Override
437                         public void onComplete() {
438                                 myFolders = new MyFolderResource(getResult());
439                                 model.getRootNodes().getList().set(0, myFolders);
440                                 model.getRootNodes().refresh();
441                                 tree.getRootTreeNode().setChildOpen(0, true);
442                                 
443                         }
444
445                         @Override
446                         public void onError(Throwable t) {
447                                 GWT.log("Error fetching root folder", t);
448                                 GSS.get().displayError("Unable to fetch root folder");
449                         }
450
451                 };
452                 DeferredCommand.addCommand(gf);
453         }
454         
455         public void updateMySharedNode(){
456                 GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, GSS.get().getCurrentUserResource().getSharedPath(), null) {
457
458                         @Override
459                         public void onComplete() {
460                                 myshared=getResult();
461                                 model.getRootNodes().getList().set(2, myshared);
462                         }
463
464                         @Override
465                         public void onError(Throwable t) {
466                                 GWT.log("Error fetching Shared Root folder", t);
467                                 GSS.get().displayError("Unable to fetch Shared Root folder");
468                         }
469                 };
470                 DeferredCommand.addCommand(gs);
471         }
472         
473         public void updateOtherNode(){
474                 GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
475                                         GSS.get().getCurrentUserResource().getOthersPath(), null) {
476
477                         @Override
478                         public void onComplete() {
479                                 others = getResult();
480                                 model.getRootNodes().getList().set(3, others);
481                         }
482
483                         @Override
484                         public void onError(Throwable t) {
485                                 GWT.log("Error fetching Others Root folder", t);
486                                 GSS.get().displayError("Unable to fetch Others Root folder");
487                         }
488                 };
489                 DeferredCommand.addCommand(go);
490         }
491         
492         
493         public RestResource getSelection(){
494                 return selectionModel.getSelectedObject();
495         }
496         
497         
498         /**
499          * Retrieve the myFolders.
500          *
501          * @return the myFolders
502          */
503         public MyFolderResource getMyFolders() {
504                 return myFolders;
505         }
506         
507         
508         /**
509          * Retrieve the myshared.
510          *
511          * @return the myshared
512          */
513         public SharedResource getMyshared() {
514                 return myshared;
515         }
516         
517         
518         /**
519          * Retrieve the trash.
520          *
521          * @return the trash
522          */
523         public TrashResource getTrash() {
524                 return trash;
525         }
526         
527         
528         /**
529          * Retrieve the others.
530          *
531          * @return the others
532          */
533         public OthersResource getOthers() {
534                 return others;
535         }
536         
537         
538         /**
539          * Retrieve the model.
540          *
541          * @return the model
542          */
543         public TreeViewModel getModel() {
544                 return model;
545         }
546         
547         
548         
549         /**
550          * Retrieve the utils.
551          *
552          * @return the utils
553          */
554         public CellTreeViewUtils getUtils() {
555                 return utils;
556         }
557         
558         public interface RefreshHandler{
559                 void onRefresh();               
560         }
561         
562         
563         public boolean isTrashOrTrashFolderSelected(){
564                 return (getSelection() instanceof TrashResource) || (getSelection() instanceof TrashFolderResource);
565         }
566         
567         public OtherUserResource getOtherUserResourceOfOtherFolder(OthersFolderResource res){
568                 TreeNode n = utils.getNodeContainingResource(tree.getRootTreeNode().setChildOpen(3, true), res);
569                 
570                 if(n!=null){
571                         if(n.getValue() instanceof OtherUserResource)
572                                 return (OtherUserResource) n.getValue();
573                         TreeNode parent = n.getParent();
574                         
575                         while (parent!=null){
576                                 if(parent.getValue() instanceof OtherUserResource)
577                                         return (OtherUserResource) parent.getValue();
578                                 parent = parent.getParent();
579                         }
580                 }
581                 return null;
582         }
583         
584         
585 }