/******************************************************************************* * Copyright (c) 2011 Arapiki Solutions Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * "Peter Smith <psmith@arapiki.com>" - initial API and * implementation and/or initial documentation *******************************************************************************/ package com.buildml.eclipse.files; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.swt.graphics.Image; import org.eclipse.ui.IEditorRegistry; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.PlatformUI; import com.buildml.eclipse.Activator; import com.buildml.eclipse.EditorOptions; import com.buildml.eclipse.bobj.UIDirectory; import com.buildml.eclipse.bobj.UIFile; import com.buildml.eclipse.bobj.UIInteger; import com.buildml.eclipse.utils.EclipsePartUtils; import com.buildml.model.IBuildStore; import com.buildml.model.IFileMgr; import com.buildml.model.IFileMgr.PathType; import com.buildml.model.IPackageMemberMgr; import com.buildml.model.IPackageMemberMgr.PackageDesc; import com.buildml.model.IPackageMgr; import com.buildml.model.IPackageRootMgr; /** * @author "Peter Smith <psmith@arapiki.com>" * */ public class FilesEditorLabelProvider implements ITableLabelProvider { /*=====================================================================================* * FIELDS/TYPES *=====================================================================================*/ /** The FilesEditor that we provide content for */ private FilesEditor editor = null; /** The manager objects for this BuildStore */ private IFileMgr fileMgr; private IPackageMgr pkgMgr; private IPackageMemberMgr pkgMemberMgr; private IPackageRootMgr pkgRootMgr; /** The ID of the top-root for our FileMgr object */ private int topRootId; /** Images we'll use when displaying a tree of files */ Image folderImage, symlinkImage; /*=====================================================================================* * CONSTRUCTORS *=====================================================================================*/ /** * Construct a new FilesEditorLabelProvider object, which provides text and image * labels for the FilesEditor class. * @param editor The editor that we're providing text/images for. * @param buildStore The BuildStore object we're graphically representing. */ public FilesEditorLabelProvider(FilesEditor editor, IBuildStore buildStore) { this.editor = editor; this.fileMgr = buildStore.getFileMgr(); this.pkgMgr = buildStore.getPackageMgr(); this.pkgMemberMgr = buildStore.getPackageMemberMgr(); this.pkgRootMgr = buildStore.getPackageRootMgr(); ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages(); folderImage = sharedImages.getImage(ISharedImages.IMG_OBJ_FOLDER); symlinkImage = null; // TODO: create an image for symlinks /* determine the top-root of this FileMgr object */ topRootId = pkgRootMgr.getRootPath("root"); } /*=====================================================================================* * PUBLIC METHODS *=====================================================================================*/ /** * @param element * @return An Image for the specified column. */ public Image getColumnImage(Object element, int columnIndex) { switch (columnIndex) { /* select an image for the tree column */ case 0: /* we only care about UIInteger types */ if ((element instanceof UIDirectory) || (element instanceof UIFile)) { UIInteger uiInt = (UIInteger)element; PathType pathType = fileMgr.getPathType(uiInt.getId()); switch (pathType) { case TYPE_INVALID: return null; case TYPE_DIR: return folderImage; case TYPE_FILE: /* * Fetch the image that's normally associated with the file type * (based on its file suffix). Rather than creating a large number * of images, we cache them in this plugin's image registry. */ String name = fileMgr.getBaseName(uiInt.getId()); return EclipsePartUtils.getImageFromFileType(name); case TYPE_SYMLINK: return symlinkImage; } } /* there is no image for the package column or the scope column. */ case 1: case 2: return null; } /* by default, show nothing */ return null; } /*-------------------------------------------------------------------------------------*/ /** * @param element * @return The text that will be displayed in the specified column. */ public String getColumnText(Object element, int columnIndex) { if ((element instanceof UIFile) || (element instanceof UIDirectory)) { UIInteger uiInt = (UIInteger)element; int pathId = uiInt.getId(); switch (columnIndex) { /* select the text for the file tree column */ case 0: return getCoalescedText(pathId); /* select text for the package column */ case 1: PackageDesc pkgInfo = pkgMemberMgr.getPackageOfMember(IPackageMemberMgr.TYPE_FILE, pathId); if (pkgInfo == null) { break; /* return "invalid" */ } if (pkgInfo.pkgId == 0) { return ""; } String pkgName = pkgMgr.getName(pkgInfo.pkgId); if (pkgName == null) { break; /* return "invalid" */ } return pkgName; /* select text for the visibility column */ case 2: pkgInfo = pkgMemberMgr.getPackageOfMember(IPackageMemberMgr.TYPE_FILE, pathId); if (pkgInfo == null) { break; /* return "invalid" */ } if (pkgInfo.pkgId == 0) { return ""; } String scopeName = pkgMemberMgr.getScopeName(pkgInfo.pkgScopeId); if (scopeName == null) { break; /* return "invalid" */ } return scopeName; } } return "<invalid>"; } /*-------------------------------------------------------------------------------------*/ /** * @param pathId The ID of the top path. * @return The coalesced path name, containing one or more path components. * */ public String getCoalescedText(int pathId) { StringBuffer sb = new StringBuffer(); Integer children[]; String roots[] = null; boolean showRoots = editor.isOptionSet(EditorOptions.OPT_SHOW_ROOTS); /* * If we're at the top of the tree, we'll want to put "/" * at the start of the name. */ if (!showRoots && fileMgr.getParentPath(pathId) == topRootId) { sb.append('/'); } /* should we try to coalesce the path? */ if (editor.isOptionSet(EditorOptions.OPT_COALESCE_DIRS)) { /* * loop, until we find a directory containing multiple entries, a * file, or a package root. */ while (true) { String pathName = fileMgr.getBaseName(pathId); sb.append(pathName); children = fileMgr.getChildPaths(pathId); /* are there roots attached here? If so, stop coalescing */ if (showRoots) { roots = pkgRootMgr.getRootsAtPath(pathId); if (roots.length != 0) { break; } } /* if there are no children or multiple children, we're done */ if (children.length != 1) { break; } /* or if the single child is not a directory, we're done */ int childId = children[0]; if (fileMgr.getPathType(childId) != PathType.TYPE_DIR) { break; } /* else, we'll coalesce the next path too */ sb.append('/'); pathId = childId; } } /* don't coalesce the path */ else { sb.append(fileMgr.getBaseName(pathId)); if (showRoots) { roots = pkgRootMgr.getRootsAtPath(pathId); } } /* if there were roots at the end of the path chain, display them */ if ((roots != null) && (roots.length != 0)) { sb.append(" ("); for (int i = 0; i < roots.length; i++) { if (i != 0) { sb.append(' '); } sb.append('@'); sb.append(roots[i]); } sb.append(')'); } return sb.toString(); } /*-------------------------------------------------------------------------------------*/ /* (non-Javadoc) * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener) */ public void addListener(ILabelProviderListener listener) { /* empty */ } /*-------------------------------------------------------------------------------------*/ /* (non-Javadoc) * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose() */ public void dispose() { /* empty */ } /*-------------------------------------------------------------------------------------*/ /* (non-Javadoc) * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String) */ public boolean isLabelProperty(Object element, String property) { return false; } /*-------------------------------------------------------------------------------------*/ /* (non-Javadoc) * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener) */ public void removeListener(ILabelProviderListener listener) { /* empty */ } /*-------------------------------------------------------------------------------------*/ }