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 gr.ebs.gss.client.rest.GetCommand;
22 import gr.ebs.gss.client.rest.MultipleGetCommand;
23 import gr.ebs.gss.client.rest.RestException;
24 import gr.ebs.gss.client.rest.resource.FolderResource;
25 import gr.ebs.gss.client.rest.resource.OthersResource;
26 import gr.ebs.gss.client.rest.resource.RestResource;
27 import gr.ebs.gss.client.rest.resource.SharedResource;
28 import gr.ebs.gss.client.rest.resource.TrashResource;
29 import gr.ebs.gss.client.rest.resource.UserResource;
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.List;
35 import com.google.gwt.cell.client.AbstractCell;
36 import com.google.gwt.cell.client.Cell;
37 import com.google.gwt.cell.client.ValueUpdater;
38 import com.google.gwt.core.client.GWT;
39 import com.google.gwt.event.logical.shared.OpenEvent;
40 import com.google.gwt.resources.client.ClientBundle;
41 import com.google.gwt.resources.client.ImageResource;
42 import com.google.gwt.resources.client.ImageResource.ImageOptions;
43 import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
44 import com.google.gwt.user.cellview.client.CellTree;
45 import com.google.gwt.user.cellview.client.TreeNode;
46 import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
47 import com.google.gwt.user.client.DeferredCommand;
48 import com.google.gwt.user.client.Event;
49 import com.google.gwt.user.client.IncrementalCommand;
50 import com.google.gwt.user.client.ui.AbstractImagePrototype;
51 import com.google.gwt.user.client.ui.Composite;
52 import com.google.gwt.user.client.ui.Tree;
53 import com.google.gwt.user.client.ui.TreeItem;
54 import com.google.gwt.view.client.AbstractDataProvider;
55 import com.google.gwt.view.client.AsyncDataProvider;
56 import com.google.gwt.view.client.HasData;
57 import com.google.gwt.view.client.ListDataProvider;
58 import com.google.gwt.view.client.Range;
59 import com.google.gwt.view.client.SelectionChangeEvent;
60 import com.google.gwt.view.client.SingleSelectionModel;
61 import com.google.gwt.view.client.TreeViewModel;
62 import com.google.gwt.view.client.SelectionChangeEvent.Handler;
63 import com.google.gwt.view.client.TreeViewModel.DefaultNodeInfo;
64 import com.google.gwt.view.client.TreeViewModel.NodeInfo;
71 public class CellTreeView extends Composite{
72 public static final boolean DONE = false;
74 private final ListDataProvider<RestResource> rootNodes = new ListDataProvider<RestResource>();
75 SingleSelectionModel<RestResource> selectionModel = new SingleSelectionModel<RestResource>();
76 FolderContextMenu menu;
79 FolderResource myFolders=null;
80 TrashResource trash = null;
81 SharedResource myshared = null;
82 OthersResource others = null;
84 TreeViewModel model = new CustomTreeModel();
86 public interface Images extends ClientBundle,Tree.Resources, FolderContextMenu.Images {
88 @Source("gr/ebs/gss/resources/folder_home.png")
91 @Source("gr/ebs/gss/resources/folder_yellow.png")
92 ImageResource folderYellow();
94 @Source("gr/ebs/gss/resources/mimetypes/document.png")
95 ImageResource document();
97 @Source("gr/ebs/gss/resources/internet.png")
98 ImageResource othersShared();
100 @Source("gr/ebs/gss/resources/edit_user.png")
101 ImageResource myShared();
103 @Source("gr/ebs/gss/resources/folder_user.png")
104 ImageResource sharedFolder();
106 @Source("gr/ebs/gss/resources/trashcan_empty.png")
107 ImageResource trash();
110 /*public interface BasicResources extends CellTree.BasicResources{
111 @ImageOptions(flipRtl = true)
112 @Source("cellTreeLoadingBasic.gif")
113 ImageResource cellTreeLoading();
115 @Source({"GssCellTreeBasic.css"})
116 CellTree.Style cellTreeStyle();
118 public interface BasicResources extends CellTree.Resources {
120 @ImageOptions(flipRtl = true)
121 @Source("cellTreeClosedItem.gif")
122 ImageResource cellTreeClosedItem();
124 @ImageOptions(flipRtl = true)
125 @Source("cellTreeLoadingBasic.gif")
126 ImageResource cellTreeLoading();
128 @ImageOptions(flipRtl = true)
129 @Source("cellTreeOpenItem.gif")
130 ImageResource cellTreeOpenItem();
132 //@Source({CellTree.Style.DEFAULT_CSS,"GssCellTreeBasic.css"})
133 @Source({"GssCellTreeBasic.css"})
134 CellTree.Style cellTreeStyle();
139 public CellTreeView(final Images _images) {
144 * Create the tree using the model. We use <code>null</code> as the default
145 * value of the root node. The default value will be passed to
146 * CustomTreeModel#getNodeInfo();
148 CellTree.Resources res = GWT.create(BasicResources.class);
149 tree = new CellTree(model,null, res){
151 public void onBrowserEvent(Event event) {
152 // TODO Auto-generated method stub
153 super.onBrowserEvent(event);
154 //GWT.log(event.getType());
157 tree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
158 Handler selectionHandler = new SelectionChangeEvent.Handler() {
160 public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
161 NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(selectionModel.getSelectedObject());
163 //GWT.log("SLECTED NODE INFO:"+nodeInfo+" "+tree.getRootTreeNode().getChildValue(1));
164 //((DefaultNodeInfo<RestResource>)nodeInfo).getValueUpdater().update(selectionModel.getSelectedObject());
165 //if(nodeInfo.getProvidesKey() instanceof FolderDataProvider)
166 //((FolderDataProvider)nodeInfo.getProvidesKey()).onRangeChanged(null);
167 if(nodeInfo.getValueUpdater()==null)
168 GWT.log("VALUE UPDATER IS NULL");
170 nodeInfo.getValueUpdater().update(selectionModel.getSelectedObject());
171 GSS.get().setCurrentSelection(selectionModel.getSelectedObject());
172 GSS.get().showFileList(true);
173 //tree.fireEvent(new OpenEvent<RestResource>(selectionModel.getSelectedObject()));
177 //OpenEvent<RestResource>.fire(tree, selectionModel.getSelectedObject());
178 selectionModel.addSelectionChangeHandler(selectionHandler);
179 sinkEvents(Event.ONCONTEXTMENU);
180 sinkEvents(Event.ONMOUSEUP);
182 DeferredCommand.addCommand(new IncrementalCommand() {
185 public boolean execute() {
186 return fetchRootFolders();
191 public void updateNode(RestResource resource){
192 NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(resource);
194 if(nodeInfo.getValueUpdater()==null)
195 GWT.log("VALUE UPDATER IS NULL");
197 nodeInfo.getValueUpdater().update(resource);
201 protected void showPopup(final int x, final int y) {
202 if (selectionModel.getSelectedObject() == null)
206 menu = new FolderContextMenu(images);
207 menu.setPopupPosition(x, y);
210 private boolean init=false;
211 public boolean fetchRootFolders() {
212 UserResource userResource = GSS.get().getCurrentUserResource();
213 if (userResource == null)
216 final String path = userResource.getFilesPath();
217 GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, null) {
220 public void onComplete() {
221 myFolders = getResult();
222 //rootNodes.setList(Arrays.asList((RestResource)rootResource));
223 //tree.getRootTreeNode().setChildOpen(0, true);
227 public void onError(Throwable t) {
228 GWT.log("Error fetching root folder", t);
229 GSS.get().displayError("Unable to fetch root folder");
233 DeferredCommand.addCommand(gf);
234 DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
236 public void onComplete() {
241 public void onError(Throwable t) {
242 if(t instanceof RestException){
243 int statusCode = ((RestException)t).getHttpStatusCode();
244 // On IE status code 1223 may be returned instead of 204.
245 if(statusCode == 204 || statusCode == 1223){
246 trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
250 GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
251 trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
256 GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, userResource.getSharedPath(), null) {
259 public void onComplete() {
260 myshared=getResult();
264 public void onError(Throwable t) {
265 GWT.log("Error fetching Shared Root folder", t);
266 GSS.get().displayError("Unable to fetch Shared Root folder");
269 DeferredCommand.addCommand(gs);
270 GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
271 userResource.getOthersPath(), null) {
274 public void onComplete() {
275 others = getResult();
276 GSS.get().removeGlassPanel();
280 public void onError(Throwable t) {
281 GWT.log("Error fetching Others Root folder", t);
282 GSS.get().displayError("Unable to fetch Others Root folder");
285 DeferredCommand.addCommand(go);
287 if(myFolders==null||trash==null||myshared==null||others==null)
289 rootNodes.setList(Arrays.asList((RestResource)myFolders,(RestResource)trash,(RestResource)myshared,(RestResource)others));
290 tree.getRootTreeNode().setChildOpen(0, true);
294 public Images getImages() {
299 class CustomTreeModel implements TreeViewModel{
300 private final Cell<RestResource> departmentCell = new AbstractCell<RestResource>("contextmenu"){
303 public void render(com.google.gwt.cell.client.Cell.Context arg0, RestResource arg1, SafeHtmlBuilder arg2) {
306 if(arg1 instanceof FolderResource){
307 FolderResource res = (FolderResource) arg1;
309 html = AbstractImagePrototype.create(images.sharedFolder()).getHTML();
310 else if(res.getParentName()==null){
311 html = AbstractImagePrototype.create(images.home()).getHTML();
314 html = AbstractImagePrototype.create(images.folderYellow()).getHTML();
315 name = res.getName();
318 if(arg1 instanceof TrashResource){
319 html = AbstractImagePrototype.create(images.trash()).getHTML();
322 if(arg1 instanceof SharedResource){
323 html = AbstractImagePrototype.create(images.myShared()).getHTML();
326 if(arg1 instanceof OthersResource){
327 html = AbstractImagePrototype.create(images.othersShared()).getHTML();
328 name = "Other's Shared";
330 arg2.appendHtmlConstant(html);
331 arg2.appendHtmlConstant("<span class='papala'>");
332 arg2.appendEscaped(name);
333 arg2.appendHtmlConstant("</span>");
336 public void onBrowserEvent(Cell.Context context, com.google.gwt.dom.client.Element parent, FolderResource value, com.google.gwt.dom.client.NativeEvent event, com.google.gwt.cell.client.ValueUpdater<FolderResource> valueUpdater) {
337 GWT.log("-->"+event.getType());
338 if(event.getType().equals("contextmenu")){
339 selectionModel.setSelected(value, true);
340 showPopup(event.getClientX(), event.getClientY());
348 public <T> NodeInfo<?> getNodeInfo(T value) {
351 return new DefaultNodeInfo<RestResource>(rootNodes, departmentCell,
352 selectionModel, null);
354 else if (value instanceof FolderResource) {
356 FolderDataProvider dataProvider = new FolderDataProvider(
357 ((FolderResource) value).getUri());
358 return new DefaultNodeInfo<RestResource>(dataProvider, departmentCell,
359 selectionModel, new ResourceValueUpdater());
361 else if (value instanceof SharedResource) {
363 FolderDataProvider dataProvider = new FolderDataProvider(
364 ((SharedResource) value).getUri());
365 return new DefaultNodeInfo<RestResource>(dataProvider, departmentCell,
366 selectionModel, null);
368 // TODO Auto-generated method stub
373 public boolean isLeaf(Object value) {
374 if(value instanceof FolderResource)
375 return ((FolderResource)value).getFolders().size()==0;
376 if(value instanceof TrashResource)
377 return ((TrashResource)value).getFolders().size()==0;
382 class ResourceValueUpdater implements ValueUpdater<RestResource>{
385 public void update(final RestResource value) {
386 if(value instanceof FolderResource){
387 GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, value.getUri(), null) {
390 public void onComplete() {
391 FolderResource rootResource = getResult();
392 ((FolderResource)value).setFiles(rootResource.getFiles());
393 if(getSelection().getUri().equals(value.getUri()))
394 selectionModel.setSelected(value, true);
395 GSS.get().onResourceUpdate(value);
399 public void onError(Throwable t) {
400 GWT.log("Error fetching root folder", t);
401 GSS.get().displayError("Unable to fetch root folder");
405 DeferredCommand.addCommand(gf);
411 class FolderDataProvider extends AsyncDataProvider<RestResource>{
412 private final String department;
414 public FolderDataProvider(String department) {
416 this.department = department;
420 protected void onRangeChanged(final HasData<RestResource> view) {
421 GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, department, null) {
424 public void onComplete() {
425 FolderResource rootResource = getResult();
426 MultipleGetCommand<FolderResource> gf2 = new MultipleGetCommand<FolderResource>(FolderResource.class,
427 rootResource.getSubfolderPaths().toArray(new String[] {}), null) {
430 public void onComplete() {
431 List<RestResource> res = new ArrayList<RestResource>();
432 res.addAll(getResult());
433 updateRowCount(res.size(), true);
434 updateRowData(0,res);
438 public void onError(Throwable t) {
439 GSS.get().displayError("Unable to fetch subfolders");
440 GWT.log("Unable to fetch subfolders", t);
444 public void onError(String p, Throwable throwable) {
445 GWT.log("Path:"+p, throwable);
449 DeferredCommand.addCommand(gf2);
454 public void onError(Throwable t) {
455 GWT.log("Error fetching root folder", t);
456 GSS.get().displayError("Unable to fetch root folder");
460 DeferredCommand.addCommand(gf);
468 public RestResource getSelection(){
469 return selectionModel.getSelectedObject();
474 * Retrieve the myFolders.
476 * @return the myFolders
478 public FolderResource getMyFolders() {
484 * Retrieve the myshared.
486 * @return the myshared
488 public SharedResource getMyshared() {
494 * Retrieve the trash.
498 public TrashResource getTrash() {
504 * Retrieve the others.
508 public OthersResource getOthers() {
514 * Retrieve the model.
518 public TreeViewModel getModel() {
522 private TreeNode getUserItem(TreeNode parent, RestResource folder) {
524 parent = tree.getRootTreeNode();
526 if (parent.getValue() instanceof RestResource &&
527 (parent.getValue().equals(folder) ||
528 ((FolderResource) parent.getValue()).getUri().equals(folder.getUri())))
530 for (int i = 0; i < parent.getChildCount(); i++) {
531 boolean op = parent.isChildOpen(i);
532 TreeNode child = parent.setChildOpen(index, open, fireEvents)(i);
533 if (child.getUserObject() instanceof FolderResource) {
534 FolderResource dto = (FolderResource) child.getUserObject();
535 if (dto.equals(folder) || dto.getUri().equals(folder.getUri()))
538 tmp = getUserItem(child, folder);