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