/*
* $Id$
*
* Copyright (c) 2008 by Christopher Hoskin.
* 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
*/
package net.sourceforge.texlipse.ui;
import net.sourceforge.texlipse.TexlipsePlugin;
import net.sourceforge.texlipse.builder.KpsewhichRunner;
import net.sourceforge.texlipse.builder.Kpath;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.core.resources.IProject;
import java.io.File;
import java.io.FileFilter;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
/**
* Adds a sub-tree to the Eclipse Project Explorer showing the Kpathsea search paths for projects
*
* @author Christopher Hoskin
*
*/
public class KpathseaProvider implements ITreeContentProvider, ILabelProvider {
/**
* We need to provide information about the nodes in the sub-tree.
* Each node will be an object. ITreeNode is the interface for
* obtaining the common node information
*/
interface ITreeNode {
Object[] getChildren();
boolean hasChildren();
String getText();
Object getParent();
Image getImage();
}
/**
*
* We will filter the search paths returned by kpsewhich for files
* with the appropriate extension. Optionally kpsewhich may search
* subdirectories.
*
*/
private class ExtFilter implements FileFilter {
protected String extension;
protected boolean folders;
public ExtFilter(String extension, boolean folders) {
this.extension = extension;
this.folders = folders;
}
public boolean accept(File pathname) {
if (pathname.isDirectory())
return folders;
else
return pathname.getName().endsWith(extension);
}
}
/**
*
* Path nodes are folders or files in the search path
*
*/
private class PathNode implements ITreeNode {
protected ITreeNode parent;
protected File path;
protected FileFilter filter;
public PathNode(ITreeNode parent, File path, FileFilter filter) {
this.parent = parent;
this.path = path;
this.filter = filter;
}
public Object[] getChildren() {
File[] files = path.listFiles(filter);
PathNode[] nodes = new PathNode[files.length];
for (int i=0; i < files.length; i++)
nodes[i] = new PathNode(this,files[i],filter);
return nodes;
}
public Object getParent() {
return parent;
}
public String getText() {
return path.getName();
}
public boolean hasChildren() {
return (path.isDirectory()&&(getChildren().length>0));
}
public Image getImage() {
// TODO Create more appropriate images
if (path.isDirectory())
return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
else if (!path.exists())
return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_TOOL_DELETE);
else
return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE);
}
}
/**
*
* Override the label of top level folders to display the full path
*
*/
private class KpathNode extends PathNode {
public KpathNode(ITreeNode parent, File path, FileFilter filter) {
super(parent, path, filter);
}
public String getText() {
return path.getPath();
}
}
/**
*
* FileTypes (e.g. .bib, .tex, .bst) to search for
*
*/
private class FileType implements ITreeNode{
protected String extension;
protected TopLevel parent;
protected Image image;
public FileType(TopLevel parent, String extension, String imageFile) {
this.parent = parent;
this.extension = extension;
this.image = TexlipsePlugin.getImage(imageFile);
}
public Object[] getChildren() {
KpsewhichRunner filesearch = new KpsewhichRunner();
try {
Kpath[] paths = filesearch.getSearchPaths(parent.getProject(), extension);
KpathNode[] nodes = new KpathNode[paths.length];
for (int i=0; i<paths.length; i++)
nodes[i] = new KpathNode(this,paths[i].path,new ExtFilter(extension,paths[i].searchChildren));
return nodes;
} catch (CoreException ce) {
TexlipsePlugin.log("Can't run Kpathsea", ce);
return null;
}
}
public boolean hasChildren() {
return (getChildren()!=null);
}
public String getText() {
return extension;
}
public Object getParent() {
return parent;
}
public Image getImage() {
return image;
}
}
/*
* This is the top level node - just a string, an image and some children
*/
private class TopLevel implements ITreeNode {
protected IProject parent;
protected FileType[] children;
public TopLevel(IProject parent) {
this.parent = parent;
//Make this configurable through the GUI later?
children = new FileType[3];
children[0] = new FileType(this,"tex","texfile");
children[1] = new FileType(this,"bib","bibfile");
children[2] = new FileType(this,"bst","bibfile");
}
public Object[] getChildren() {
return children;
}
public boolean hasChildren() {
return true;
}
public String getText() {
return "Search Paths";
}
public Object getParent() {
return parent;
}
public IProject getProject() {
return parent;
}
public Image getImage() {
// TODO Generate a better icon
return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
}
}
/*
* Implement ITreeContentProvider interface
*/
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
*/
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof IProject)
return new Object[] { this.new TopLevel((IProject) parentElement) };
else if (parentElement instanceof ITreeNode)
return ((ITreeNode) parentElement).getChildren();
else
return null;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
*/
public Object getParent(Object element) {
if (element instanceof ITreeNode)
return ((ITreeNode) element).getParent();
else
return null;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
*/
public boolean hasChildren(Object element) {
if (element instanceof ITreeNode)
return ((ITreeNode) element).hasChildren();
else
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
*/
public Object[] getElements(Object inputElement) {
//When ProjectExplorer calls this function it passes WorkspaceRoot as inputElement.
//Because our highest nodes are children of IProject
//we never get called
return null;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
*/
public void dispose() {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
*/
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
// TODO Auto-generated method stub
}
/*
* Implement ILabelProvider interface
*/
/*
* (non-Javadoc)
* @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
*/
public Image getImage(Object element) {
if (element instanceof ITreeNode)
return ((ITreeNode) element).getImage();
else
return null;
}
public String getText(Object element) {
if (element instanceof ITreeNode)
return ((ITreeNode) element).getText();
else if (element instanceof File)
return ((File) element).getName();
else
return element.toString();
}
public void addListener(ILabelProviderListener listener) {
// TODO Auto-generated method stub
}
public boolean isLabelProperty(Object element, String property) {
// TODO Auto-generated method stub
return false;
}
public void removeListener(ILabelProviderListener listener) {
// TODO Auto-generated method stub
}
}