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