/** * OpenKM, Open Document Management System (http://www.openkm.com) * Copyright (c) 2006-2011 Paco Avila & Josep Llort * * No bytes were intentionally harmed during the development of this application. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package com.openkm.frontend.client.widget.wizard; import java.util.Iterator; import java.util.List; import com.google.gwt.core.client.GWT; import com.google.gwt.event.logical.shared.SelectionEvent; import com.google.gwt.event.logical.shared.SelectionHandler; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.rpc.ServiceDefTarget; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Tree; import com.google.gwt.user.client.ui.TreeItem; import com.openkm.frontend.client.Main; import com.openkm.frontend.client.bean.GWTFolder; import com.openkm.frontend.client.contants.service.RPCService; import com.openkm.frontend.client.service.OKMFolderService; import com.openkm.frontend.client.service.OKMFolderServiceAsync; import com.openkm.frontend.client.service.OKMRepositoryService; import com.openkm.frontend.client.service.OKMRepositoryServiceAsync; import com.openkm.frontend.client.util.Util; /** * Folder tree * * @author jllort * */ public class FolderSelectTree extends Composite { private Tree tree; private TreeItem actualItem; private final OKMFolderServiceAsync folderService = (OKMFolderServiceAsync) GWT.create(OKMFolderService.class); private final OKMRepositoryServiceAsync repositoryService = (OKMRepositoryServiceAsync) GWT.create(OKMRepositoryService.class); TreeItem rootItem = new TreeItem(Util.imageItemHTML("img/menuitem_childs.gif", "root_schema", "top")); /** * Folder Tree */ public FolderSelectTree() { tree = new Tree(); rootItem.setStyleName("okm-TreeItem"); rootItem.setUserObject(new GWTFolder()); rootItem.setSelected(true); rootItem.setState(true); tree.setStyleName("okm-Tree"); tree.addItem(rootItem); tree.addSelectionHandler(new SelectionHandler<TreeItem>() { @Override public void onSelection(SelectionEvent<TreeItem> event) { boolean refresh = true; TreeItem item = event.getSelectedItem(); // Enables or disables move button ( evalues security to move to folder with permissions ) if (rootItem.equals(item)) { Main.get().wizardPopup.categoriesWidget.enable(false); } else { Main.get().wizardPopup.categoriesWidget.enable(true); } // Case that not refreshing tree and file browser ( right click ) if (actualItem.equals(item)) { refresh = false; } else { // Disables actual item because on changing active node by // application this it's not changed automatically if (!actualItem.equals(item)) { actualItem.setSelected(false); actualItem = item; } else { refresh = false; } } if (refresh) { refresh(true); } } }); actualItem = tree.getItem(0); initWidget(tree); } /** * Resets all tree values */ public void reset() { actualItem = rootItem; actualItem.setSelected(true); while (actualItem.getChildCount()>0) { actualItem.getChild(0).remove(); } getCategories(); } /** * Refresh asyncronous subtree branch */ final AsyncCallback<List<GWTFolder>> callbackGetChilds = new AsyncCallback<List<GWTFolder>>() { public void onSuccess(List<GWTFolder> result) { boolean directAdd = true; // If has no childs directly add values is permited if (actualItem.getChildCount() > 0) { directAdd = false; // to prevent remote folder remove it disables all tree branch // items and after sequentially activate hideAllBranch(actualItem); } // On refreshing not refreshed the actual item values but must // ensure that has childs value is consistent if (result.isEmpty()) { ((GWTFolder) actualItem.getUserObject()).setHasChilds(false); } else { ((GWTFolder) actualItem.getUserObject()).setHasChilds(true); } // Ads folders childs if exists for (Iterator<GWTFolder> it = result.iterator(); it.hasNext();) { GWTFolder folder = it.next(); TreeItem folderItem = new TreeItem(folder.getName()); folderItem.setUserObject(folder); folderItem.setStyleName("okm-TreeItem"); // If has no childs directly add values is permited, else // evalues each node to refresh, remove or add if (directAdd) { evaluesFolderIcon(folderItem); actualItem.addItem(folderItem); } else { // sequentially activate items and refreshes values addFolder(actualItem,folderItem); } } actualItem.setState(true); evaluesFolderIcon(actualItem); } public void onFailure(Throwable caught) { Main.get().showError("GetChilds", caught); } }; /** * Gets asyncronous root node */ final AsyncCallback<GWTFolder> callbackGetCategoriesFolder = new AsyncCallback<GWTFolder>() { public void onSuccess(GWTFolder result) { // Only executes on initalization and the actualItem is root // element on initialization //We put the id on root actualItem.setUserObject(result); evaluesFolderIcon(actualItem); actualItem.setState(true); actualItem.setSelected(true); getChilds(result.getPath()); } public void onFailure(Throwable caught) { Main.get().showError("GetCategoriesFolder", caught); } }; /** * Refresh the folders on a item node * * @param path The folder path selected to list items */ public void getChilds(String path) { ServiceDefTarget endPoint = (ServiceDefTarget) folderService; endPoint.setServiceEntryPoint(RPCService.FolderService); folderService.getChilds(path, callbackGetChilds); } /** * Gets the root */ public void getCategories() { ServiceDefTarget endPoint = (ServiceDefTarget) repositoryService; endPoint.setServiceEntryPoint(RPCService.RepositoryService); repositoryService.getCategoriesFolder(callbackGetCategoriesFolder); } /** * Refresh the tree node */ public void refresh(boolean reset) { String path = ((GWTFolder) actualItem.getUserObject()).getPath(); getChilds(path); } /** * Hides all items on a brach * * @param actualItem The actual item active */ public void hideAllBranch(TreeItem actualItem) { int i = 0; int count = actualItem.getChildCount(); for (i=0; i<count; i++) { actualItem.getChild(i).setVisible(false); } } /** * Adds folders to actual item if not exists or refreshes it values * * @param actualItem The actual item active * @param newItem New item to be added, or refreshed */ public void addFolder(TreeItem actualItem , TreeItem newItem) { int i = 0; boolean found = false; int count = actualItem.getChildCount(); GWTFolder folder; GWTFolder newFolder = (GWTFolder) newItem.getUserObject(); String folderPath = newFolder.getPath(); for (i=0; i<count; i++) { folder = (GWTFolder) actualItem.getChild(i).getUserObject(); // If item is found actualizate values if ((folder).getPath().equals(folderPath)) { found = true; actualItem.getChild(i).setVisible(true); actualItem.getChild(i).setUserObject(newFolder); evaluesFolderIcon(actualItem.getChild(i)); } } if (!found) { evaluesFolderIcon(newItem); actualItem.addItem(newItem); } } /** * Gets the actual Uuid of the selected directory tree * * @return The actual path of selected directory */ public GWTFolder getCategory() { return ((GWTFolder) actualItem.getUserObject()); } /** * Evalues actual folder icon to prevent other user interaction with the same folder * this ensures icon and object hasChildsValue are consistent */ public void evaluesFolderIcon(TreeItem item) { GWTFolder folderItem = (GWTFolder) item.getUserObject(); preventFolderInconsitences(item); // Looks if must change icon on parent if now has no childs and properties with user security atention if (folderItem.getHasChilds()) { item.setHTML(Util.imageItemHTML("img/menuitem_childs.gif", folderItem.getName(), "top")); } else { item.setHTML(Util.imageItemHTML("img/menuitem_empty.gif", folderItem.getName(), "top")); } } /** * Prevents folder incosistences between server ( multi user deletes folder ) and tree * nodes drawed * * @param item The tree node */ public void preventFolderInconsitences(TreeItem item) { GWTFolder folderItem = (GWTFolder) item.getUserObject(); // Case that must remove all items node if (item.getChildCount() > 0 && !folderItem.getHasChilds()) { while (item.getChildCount() > 0) { item.getChild(0).remove(); } } if (item.getChildCount()< 1 && !folderItem.getHasChilds()) { folderItem.setHasChilds(false); } } }