2 * Copyright 2011 Electronic Business Systems Ltd.
4 * This file is part of GSS.
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.
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.
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/>.
19 package gr.ebs.gss.client;
21 import static com.google.gwt.query.client.GQuery.$;
22 import gr.ebs.gss.client.CellTreeView.Images;
23 import gr.ebs.gss.client.CellTreeView.RefreshHandler;
24 import gr.ebs.gss.client.rest.GetCommand;
25 import gr.ebs.gss.client.rest.MultipleGetCommand;
26 import gr.ebs.gss.client.rest.RestException;
27 import gr.ebs.gss.client.rest.resource.FileResource;
28 import gr.ebs.gss.client.rest.resource.FolderResource;
29 import gr.ebs.gss.client.rest.resource.MyFolderResource;
30 import gr.ebs.gss.client.rest.resource.OtherUserResource;
31 import gr.ebs.gss.client.rest.resource.OthersFolderResource;
32 import gr.ebs.gss.client.rest.resource.OthersResource;
33 import gr.ebs.gss.client.rest.resource.RestResource;
34 import gr.ebs.gss.client.rest.resource.RestResourceWrapper;
35 import gr.ebs.gss.client.rest.resource.SharedFolderResource;
36 import gr.ebs.gss.client.rest.resource.SharedResource;
37 import gr.ebs.gss.client.rest.resource.TrashFolderResource;
38 import gr.ebs.gss.client.rest.resource.TrashResource;
39 import gwtquery.plugins.draggable.client.DraggableOptions;
40 import gwtquery.plugins.draggable.client.DraggableOptions.CursorAt;
41 import gwtquery.plugins.draggable.client.DraggableOptions.DragFunction;
42 import gwtquery.plugins.draggable.client.DraggableOptions.RevertOption;
43 import gwtquery.plugins.draggable.client.events.DragContext;
44 import gwtquery.plugins.droppable.client.DroppableOptions;
45 import gwtquery.plugins.droppable.client.DroppableOptions.DroppableFunction;
46 import gwtquery.plugins.droppable.client.events.DragAndDropContext;
47 import gwtquery.plugins.droppable.client.gwt.DragAndDropNodeInfo;
49 import java.util.ArrayList;
50 import java.util.Arrays;
51 import java.util.HashMap;
52 import java.util.List;
55 import com.google.gwt.cell.client.AbstractCell;
56 import com.google.gwt.cell.client.Cell;
57 import com.google.gwt.cell.client.ValueUpdater;
58 import com.google.gwt.core.client.GWT;
59 import com.google.gwt.dom.client.Style.Cursor;
60 import com.google.gwt.safehtml.client.SafeHtmlTemplates;
61 import com.google.gwt.safehtml.shared.SafeHtml;
62 import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
63 import com.google.gwt.user.client.DeferredCommand;
64 import com.google.gwt.user.client.ui.AbstractImagePrototype;
65 import com.google.gwt.view.client.AsyncDataProvider;
66 import com.google.gwt.view.client.HasData;
67 import com.google.gwt.view.client.ListDataProvider;
68 import com.google.gwt.view.client.ProvidesKey;
69 import com.google.gwt.view.client.SingleSelectionModel;
70 import com.google.gwt.view.client.TreeViewModel;
78 public class CellTreeViewModel implements TreeViewModel{
79 private final ListDataProvider<RestResource> rootNodes = new ListDataProvider<RestResource>();
80 private Map<String,FolderResource> folderCache=new HashMap<String, FolderResource>();
82 SingleSelectionModel<RestResource> selectionModel;
83 Map<String, MyFolderDataProvider> mymap = new HashMap<String, MyFolderDataProvider>();
84 static interface Templates extends SafeHtmlTemplates {
85 Templates INSTANCE = GWT.create(Templates.class);
87 @Template(" <div id='dragHelper' class='{0}'></div>")
88 SafeHtml outerHelper(String cssClassName);
91 static void configureDragOperation(DraggableOptions options) {
93 // set a custom element as drag helper. The content of the helper will be
94 // set when the drag will start
95 options.setHelper($(Templates.INSTANCE.outerHelper(
97 // opacity of the drag helper
98 options.setOpacity((float) 0.9);
99 // cursor during the drag operation
100 options.setCursor(Cursor.MOVE);
101 // the cell being greater than the helper, force the position of the
102 // helper on the mouse cursor.
103 options.setCursorAt(new CursorAt(10, 10, null, null));
104 // append the helper to the body element
105 options.setAppendTo("body");
106 // set the revert option
107 options.setRevert(RevertOption.ON_INVALID_DROP);
108 // use a Function to fill the content of the helper
109 // we could also add a DragStartEventHandler on the DragAndDropTreeCell and
110 // DragAndDropCellList.
111 options.setOnDragStart(new DragFunction() {
112 public void f(DragContext context) {
113 RestResourceWrapper memberInfo = context.getDraggableData();
114 context.getHelper().setInnerHTML(memberInfo.getName());
123 public CellTreeViewModel(final Images _images,SingleSelectionModel<RestResource> selectionModel ) {
126 this.selectionModel=selectionModel;
129 private final Cell<RestResource> departmentCell = new AbstractCell<RestResource>("contextmenu"){
132 public void render(com.google.gwt.cell.client.Cell.Context arg0, RestResource arg1, SafeHtmlBuilder arg2) {
135 if(arg1 instanceof TrashFolderResource){
136 html = AbstractImagePrototype.create(images.folderYellow()).getHTML();
137 FolderResource res = ((RestResourceWrapper)arg1).getResource();
140 else if(arg1 instanceof RestResourceWrapper){
141 FolderResource res = ((RestResourceWrapper)arg1).getResource();
143 html = AbstractImagePrototype.create(images.sharedFolder()).getHTML();
144 else if(res.getParentName()==null){
145 html = AbstractImagePrototype.create(images.home()).getHTML();
148 html = AbstractImagePrototype.create(images.folderYellow()).getHTML();
149 name = res.getName();
152 else if(arg1 instanceof TrashResource){
153 html = AbstractImagePrototype.create(images.trash()).getHTML();
157 else if(arg1 instanceof SharedResource){
158 html = AbstractImagePrototype.create(images.myShared()).getHTML();
161 else if(arg1 instanceof OthersResource){
162 html = AbstractImagePrototype.create(images.othersShared()).getHTML();
163 name = "Other's Shared";
165 else if(arg1 instanceof OtherUserResource){
166 html = AbstractImagePrototype.create(images.permUser()).getHTML();
167 name = ((OtherUserResource)arg1).getName();
169 arg2.appendHtmlConstant(html);
170 arg2.appendHtmlConstant("<span class='papala'>");
171 arg2.appendEscaped(name);
172 arg2.appendHtmlConstant("</span>");
175 public void onBrowserEvent(Cell.Context context, com.google.gwt.dom.client.Element parent, RestResource value, com.google.gwt.dom.client.NativeEvent event, com.google.gwt.cell.client.ValueUpdater<RestResource> valueUpdater) {
176 if(event.getType().equals("contextmenu")){
177 selectionModel.setSelected(value, true);
178 GSS.get().getTreeView().showPopup(event.getClientX(), event.getClientY());
186 public <T> NodeInfo<?> getNodeInfo(final T value) {
189 return new DragAndDropNodeInfo<RestResource>(getRootNodes(), departmentCell,
190 selectionModel, null);
192 else if (value instanceof MyFolderResource) {
194 MyFolderDataProvider dataProvider = new MyFolderDataProvider(
195 ((MyFolderResource) value),MyFolderResource.class);
196 DragAndDropNodeInfo<RestResource> n = new DragAndDropNodeInfo<RestResource>(dataProvider, departmentCell,
197 selectionModel, new ResourceValueUpdater());
198 //nodeInfos.put(((MyFolderResource) value).getUri(), n);
199 mymap.put(((MyFolderResource) value).getUri(), dataProvider);
200 DroppableOptions options = n.getDroppableOptions();
201 options.setDroppableHoverClass("droppableHover");
202 // use a DroppableFunction here. We can also add a DropHandler in the tree
204 options.setOnOver(new DroppableFunction() {
207 public void f(DragAndDropContext context) {
208 GWT.log("-->OnActivate:"+context.getDroppableData());
209 if(context.getDroppableData()!=null && context.getDroppableData() instanceof RestResource){
210 GSS.get().getTreeView().openNodeContainingResource((RestResource) context.getDroppableData());
215 options.setOnDrop(new DroppableFunction() {
217 public void f(DragAndDropContext context) {
219 DnDFolderPopupMenu popup ;
220 if(context.getDraggableData() instanceof FileResource){
221 popup = new DnDFolderPopupMenu(images, ((MyFolderResource) context.getDroppableData()).getResource(), Arrays.asList(context.getDraggableData()));
224 popup = new DnDFolderPopupMenu(images, ((MyFolderResource) context.getDroppableData()).getResource(), context.getDraggableData());
225 int left = context.getDroppable().getAbsoluteLeft() + 40;
226 int top = context.getDroppable().getAbsoluteTop() + 20;
227 popup.setPopupPosition(left, top);
232 // permission cell are not draggable
233 //n.setCellDroppableOnly();
234 configureDragOperation(n.getDraggableOptions());
237 else if (value instanceof SharedResource) {
239 MyFolderDataProvider dataProvider = new MyFolderDataProvider(
240 ((SharedResource) value), SharedFolderResource.class);
241 return new DragAndDropNodeInfo<RestResource>(dataProvider, departmentCell,
242 selectionModel, new ResourceValueUpdater());
244 else if (value instanceof TrashResource) {
246 ListDataProvider<RestResource> trashProvider = new ListDataProvider<RestResource>();
247 List<RestResource> r = new ArrayList<RestResource>();
248 for(FolderResource f : GSS.get().getTreeView().getTrash().getFolders()){
249 r.add(new TrashFolderResource(f));
251 trashProvider.setList(r);
252 return new DragAndDropNodeInfo<RestResource>(trashProvider, departmentCell,
253 selectionModel, new ResourceValueUpdater());
255 else if (value instanceof OthersResource) {
257 OthersDataProvider dataProvider = new OthersDataProvider(
258 ((OthersResource) value), SharedFolderResource.class);
259 return new DragAndDropNodeInfo<RestResource>(dataProvider, departmentCell,
260 selectionModel, null);
262 else if (value instanceof SharedFolderResource) {
264 MyFolderDataProvider dataProvider = new MyFolderDataProvider(
265 ((SharedFolderResource) value),SharedFolderResource.class);
266 DragAndDropNodeInfo<RestResource> n = new DragAndDropNodeInfo<RestResource>(dataProvider, departmentCell,
267 selectionModel, new ResourceValueUpdater());
268 //nodeInfos.put(((SharedFolderResource) value).getUri(), n);
269 DroppableOptions options = n.getDroppableOptions();
270 options.setDroppableHoverClass("droppableHover");
271 // use a DroppableFunction here. We can also add a DropHandler in the tree
273 options.setOnDrop(new DroppableFunction() {
275 public void f(DragAndDropContext context) {
280 // permission cell are not draggable
281 n.setCellDroppableOnly();
284 else if (value instanceof OthersFolderResource) {
286 MyFolderDataProvider dataProvider = new MyFolderDataProvider(
287 ((OthersFolderResource) value),OthersFolderResource.class);
288 DragAndDropNodeInfo<RestResource> n = new DragAndDropNodeInfo<RestResource>(dataProvider, departmentCell,
289 selectionModel, new ResourceValueUpdater());
290 //nodeInfos.put(((OthersFolderResource) value).getUri(), n);
291 DroppableOptions options = n.getDroppableOptions();
292 options.setDroppableHoverClass("droppableHover");
293 // use a DroppableFunction here. We can also add a DropHandler in the tree
295 options.setOnDrop(new DroppableFunction() {
297 public void f(DragAndDropContext context) {
302 // permission cell are not draggable
303 n.setCellDroppableOnly();
306 else if (value instanceof OtherUserResource) {
308 MyFolderDataProvider dataProvider = new MyFolderDataProvider(
309 ((OtherUserResource) value),OthersFolderResource.class);
310 DragAndDropNodeInfo<RestResource> n = new DragAndDropNodeInfo<RestResource>(dataProvider, departmentCell,
311 selectionModel, new ResourceValueUpdater());
312 //nodeInfos.put(((OtherUserResource) value).getUri(), n);
313 DroppableOptions options = n.getDroppableOptions();
314 options.setDroppableHoverClass("droppableHover");
315 // use a DroppableFunction here. We can also add a DropHandler in the tree
317 options.setOnDrop(new DroppableFunction() {
319 public void f(DragAndDropContext context) {
324 // permission cell are not draggable
325 n.setCellDroppableOnly();
328 // TODO Auto-generated method stub
333 public boolean isLeaf(Object value) {
334 if(value instanceof RestResourceWrapper)
335 return ((RestResourceWrapper)value).getResource().getFolders().size()==0;
336 else if(value instanceof TrashResource)
337 return ((TrashResource)value).getFolders().size()==0;
338 else if(value instanceof SharedResource)
339 return ((SharedResource)value).getFolders().size()==0;
340 else if(value instanceof OthersResource)
341 return ((OthersResource)value).getOtherUsers().size()==0;
342 else if(value instanceof OtherUserResource)
343 return ((OtherUserResource)value).getFolders().size()==0;
347 class ResourceValueUpdater implements ValueUpdater<RestResource>{
350 public void update(final RestResource value) {
351 if(value instanceof MyFolderResource){
352 GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, value.getUri(), null) {
355 public void onComplete() {
356 FolderResource rootResource = getResult();
357 //((MyFolderResource)value).getResource().setFiles(rootResource.getFiles());
358 ((MyFolderResource)value).setResource(rootResource);
359 if(GSS.get().getTreeView().getSelection().getUri().equals(value.getUri()))
360 selectionModel.setSelected(value, true);
361 GWT.log("UPDATYING");
362 GSS.get().onResourceUpdate(value);
367 public void onError(Throwable t) {
368 GWT.log("Error fetching root folder", t);
369 GSS.get().displayError("Unable to fetch root folder");
373 DeferredCommand.addCommand(gf);
375 if(value instanceof TrashResource){
376 DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
378 public void onComplete() {
379 //trash = getResult();
380 for(RestResource r : getRootNodes().getList()){
381 if(r instanceof TrashResource)
382 getRootNodes().getList().set(getRootNodes().getList().indexOf(r),GSS.get().getTreeView().getTrash());
384 GSS.get().getTreeView().updateNodeChildren(GSS.get().getTreeView().getTrash());
388 public void onError(Throwable t) {
389 if(t instanceof RestException){
390 int statusCode = ((RestException)t).getHttpStatusCode();
391 // On IE status code 1223 may be returned instead of 204.
392 if(statusCode == 204 || statusCode == 1223){
393 //trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
397 GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
398 //GSS.get().getTreeView().getTrash() = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
408 class MyFolderDataProvider extends AsyncDataProvider<RestResource>{
409 private RestResource restResource;
410 private Class resourceClass;
411 public MyFolderDataProvider(RestResource department, Class resourceClass) {
412 super(new ProvidesKey<RestResource>() {
415 public Object getKey(RestResource item) {
416 return item.getUri();
418 this.restResource = department;
419 this.resourceClass=resourceClass;
420 //CellTreeView.this.mymap.put(department.getUri(), MyFolderDataProvider.this);
424 protected void onRangeChanged(final HasData<RestResource> view) {
429 * Retrieve the restResource.
431 * @return the restResource
433 public RestResource getRestResource() {
439 * Modify the restResource.
441 * @param restResource the restResource to set
443 public void setRestResource(RestResource restResource) {
444 this.restResource = restResource;
446 List<RestResource> res =null;
447 public void refresh(final RefreshHandler refresh){
448 GWT.log("******************************************");
449 GWT.log("[REFRESHING]:"+restResource.getUri());
450 GWT.log("******************************************");
451 FolderResource cache = null;
452 if(restResource instanceof RestResourceWrapper && !((RestResourceWrapper)restResource).getResource().isNeedsExpanding())
453 cache = ((RestResourceWrapper)restResource).getResource();
454 GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, restResource.getUri(),cache ) {
457 public void onComplete() {
458 if(restResource instanceof RestResourceWrapper){
459 ((RestResourceWrapper)restResource).setResource(getResult());//restResource = getResult();
460 ((RestResourceWrapper)restResource).getResource().setNeedsExpanding(false);
462 if(usedCachedVersion()&&res!=null){
463 updateRowCount(res.size(), true);
464 updateRowData(0,res);
467 String[] folderPaths = null;
468 if(resourceClass.equals(MyFolderResource.class))
469 folderPaths=((MyFolderResource) restResource).getResource().getSubfolderPaths().toArray(new String[] {});
470 else if(resourceClass.equals(SharedFolderResource.class) && restResource instanceof SharedResource)
471 folderPaths=((SharedResource) restResource).getSubfolderPaths().toArray(new String[] {});
472 else if(resourceClass.equals(SharedFolderResource.class)){
473 folderPaths=((SharedFolderResource) restResource).getResource().getSubfolderPaths().toArray(new String[] {});
474 GWT.log("------------>"+folderPaths);
476 else if(resourceClass.equals(TrashFolderResource.class))
477 folderPaths=((TrashFolderResource) restResource).getResource().getSubfolderPaths().toArray(new String[] {});
478 else if(resourceClass.equals(OthersFolderResource.class) && restResource instanceof OtherUserResource)
479 folderPaths=((OtherUserResource) restResource).getSubfolderPaths().toArray(new String[] {});
480 else if(resourceClass.equals(OthersFolderResource.class))
481 folderPaths=((OthersFolderResource) restResource).getResource().getSubfolderPaths().toArray(new String[] {});
482 MultipleGetCommand.Cached[] cached = null;
483 if(restResource instanceof RestResourceWrapper)
484 cached=((RestResourceWrapper)restResource).getResource().getCache();
485 MultipleGetCommand<FolderResource> gf2 = new MultipleGetCommand<FolderResource>(FolderResource.class,
486 folderPaths, cached) {
489 public void onComplete() {
490 res = new ArrayList<RestResource>();
491 for(FolderResource r : getResult()){
495 else if(resourceClass.equals(MyFolderResource.class))
496 res.add(new MyFolderResource(r));
497 else if(resourceClass.equals(SharedFolderResource.class)){
498 GWT.log("ADDING:"+r.getUri());
499 res.add(new SharedFolderResource(r));
501 else if(resourceClass.equals(TrashFolderResource.class))
502 res.add(new TrashFolderResource(r));
503 else if(resourceClass.equals(OthersFolderResource.class))
504 res.add(new OthersFolderResource(r));
506 if(restResource instanceof RestResourceWrapper)
507 ((RestResourceWrapper)restResource).getResource().setFolders(getResult());
508 updateRowCount(res.size(), true);
509 updateRowData(0,res);
515 public void onError(Throwable t) {
516 GSS.get().displayError("Unable to fetch subfolders");
517 GWT.log("Unable to fetch subfolders", t);
521 public void onError(String p, Throwable throwable) {
522 GWT.log("Path:"+p, throwable);
526 DeferredCommand.addCommand(gf2);
531 public void onError(Throwable t) {
533 GWT.log("Error fetching root folder", t);
534 GSS.get().displayError("Unable to fetch root folder");
538 DeferredCommand.addCommand(gf);
543 class OthersDataProvider extends AsyncDataProvider<RestResource>{
544 private RestResource restResource;
545 private Class resourceClass;
546 public OthersDataProvider(RestResource department, Class resourceClass) {
547 super(new ProvidesKey<RestResource>() {
550 public Object getKey(RestResource item) {
551 return item.getUri();
553 this.restResource = department;
554 this.resourceClass=resourceClass;
555 //CellTreeView.this.mymap.put(department.getUri(), OthersDataProvider.this);
559 protected void onRangeChanged(final HasData<RestResource> view) {
564 * Retrieve the restResource.
566 * @return the restResource
568 public RestResource getRestResource() {
574 * Modify the restResource.
576 * @param restResource the restResource to set
578 public void setRestResource(RestResource restResource) {
579 this.restResource = restResource;
582 public void refresh(final RefreshHandler refresh){
583 GWT.log("******************************************");
584 GWT.log("[REFRESHING]:"+restResource.getUri());
585 GWT.log("******************************************");
586 GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
587 restResource.getUri(), null) {
590 public void onComplete() {
591 final OthersResource others = getResult();
592 MultipleGetCommand<OtherUserResource> gogo = new MultipleGetCommand<OtherUserResource>(OtherUserResource.class,
593 others.getOthers().toArray(new String[] {}), null) {
596 public void onComplete() {
597 List<OtherUserResource> res = getResult();
598 updateRowCount(res.size(), true);
599 List<RestResource> r = new ArrayList<RestResource>();
605 public void onError(Throwable t) {
606 GWT.log("Error fetching Others Root folder", t);
607 GSS.get().displayError("Unable to fetch Others Root folder");
611 public void onError(String p, Throwable throwable) {
612 GWT.log("Path:"+p, throwable);
615 DeferredCommand.addCommand(gogo);
619 public void onError(Throwable t) {
620 GWT.log("Error fetching Others Root folder", t);
621 GSS.get().displayError("Unable to fetch Others Root folder");
624 DeferredCommand.addCommand(go);
631 * Retrieve the rootNodes.
633 * @return the rootNodes
635 public ListDataProvider<RestResource> getRootNodes() {
641 * Retrieve the mymap.
645 public Map<String, MyFolderDataProvider> getMymap() {