package biz.volantec.utils.widgets; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.DecoratingLabelProvider; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ResourceWorkingSetFilter; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; /** * * FileDialog that is workspace relative and can start at a given root element * * Basically embeds the relevant parts of the resource navigator in a dialog. * * The workhorse here is the WorkbenchContentProvider I'm sure... * * * * @author Frank Sauer * */ public class WSFileDialog extends Dialog { private TreeViewer viewer; private final IResource rootElement; private final boolean expand; private String[] extensions; private final FilePatternFilter patternFilter = new FilePatternFilter(); private final ResourceWorkingSetFilter workingSetFilter = new ResourceWorkingSetFilter(); private final IWorkingSet workingSet; private final int selectionStyle; private IResource[] result; private final String title; /** * * @param parentShell * this shell will be blocked by the modal WSFileDialog * * @param selectionStyle * must be SWT.SINGLE or SWT.MULTI * * @param title * the dialog's title * * @param rootElement * resource to be the rootElement for the tree * * @param expand * if true, the root element will be expanded * * @param extensions * if specified only files with these extensions are shown * * @param workingSet * if specified only files in this workingSet are shown * */ public WSFileDialog(Shell parentShell, int selectionStyle, String title, IResource rootElement, boolean expand, String[] extensions, IWorkingSet workingSet) { super(parentShell); setShellStyle(getShellStyle() | SWT.RESIZE); this.title = title; this.rootElement = rootElement; this.expand = expand; this.extensions = extensions; this.workingSet = workingSet; this.selectionStyle = selectionStyle; } /** * * Open on the workspace root without filters or workingset * * * * @param parentShell * this shell will be blocked by the modal WSFileDialog * * @param selectionStyle * must be SWT.SINGLE or SWT.MULTI * * @param title * the dialog title * */ public WSFileDialog(Shell parentShell, int selectionStyle, String title) { this( parentShell, selectionStyle, title, ResourcesPlugin.getWorkspace().getRoot(), true, null, null); } /** * * Only files with the given file extensions will be shown * * @param extensions * */ public void setExtensions(String[] extensions) { this.extensions = extensions; } /* * (non-Javadoc) * * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets .Composite) */ @Override protected Control createDialogArea(Composite parent) { Composite comp = (Composite) super.createDialogArea(parent); getShell().setText(title); TreeViewer viewer = createViewer(comp); GridData data = new GridData(GridData.FILL_BOTH); data.grabExcessHorizontalSpace = true; data.grabExcessVerticalSpace = true; data.heightHint = 400; data.widthHint = 300; viewer.getControl().setLayoutData(data); this.viewer = viewer; return comp; } protected TreeViewer createViewer(Composite parent) { final TreeViewer viewer = new TreeViewer(parent, selectionStyle | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); viewer.setUseHashlookup(true); initContentProvider(viewer); initLabelProvider(viewer); initFilters(viewer); viewer.setInput(rootElement); if (expand) { viewer.expandToLevel(2); } viewer.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { ISelection selection = viewer.getSelection(); if (!selection.isEmpty()) { okPressed(); } } }); return viewer; } /** * * Attach the filters to the tree viewer * * @param viewer * */ protected void initFilters(TreeViewer viewer) { viewer.addFilter(patternFilter); if (workingSet != null) { workingSetFilter.setWorkingSet(workingSet); viewer.addFilter(workingSetFilter); } } /** * * This is the key, the WorkBenchContentProvider provides us * * with all the resource information * * @param viewer * */ protected void initContentProvider(TreeViewer viewer) { viewer.setContentProvider(new WorkbenchContentProvider()); } protected void initLabelProvider(TreeViewer viewer) { viewer.setLabelProvider( new DecoratingLabelProvider( new WorkbenchLabelProvider(), PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator())); } /** * * process the tree selection and keep as the resultIResource[] until needed by our client * * * * @see org.eclipse.jface.dialogs.Dialog#okPressed() * */ @Override protected void okPressed() { ISelection selection = viewer.getSelection(); List<IResource> data = new ArrayList<IResource>(); if (!selection.isEmpty()) { if (selection instanceof IStructuredSelection) { IStructuredSelection sel = (IStructuredSelection) selection; for (Object next : sel.toList()) { IResource resource = null; if (next instanceof IResource) { resource = (IResource) next; } else if (next instanceof IAdaptable) { if (resource == null) { resource = (IResource) ((IAdaptable) next).getAdapter(IResource.class); } } if (resource != null) { data.add(resource); } } } } result = data.toArray(new IResource[] {}); super.okPressed(); } /** * * Get the single selection result if any or the first selected * * element if SWT.MULTI was used as the selectionType * * @return one selected resource or null if none or canceled * */ public IResource getSingleResult() { if (getReturnCode() == OK) { return getMultiResult()[0]; } else { return null; } } /** * * Get an array of selected resources or null if canceled * * @return selected resources or null if none or canceled * */ public IResource[] getMultiResult() { if (getReturnCode() == OK) { return result; } else { return null; } } /** * * ViewerFilter to only show non-derived folders and those files matching the file extensions * * @author Frank Sauer * */ private class FilePatternFilter extends ViewerFilter { /** * Select all folders and files matching the desired file extensions * * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, * java.lang.Object) * */ @Override public boolean select(Viewer viewer, Object parentElement, Object element) { if (extensions == null || extensions.length == 0) { return true; } IResource resource = null; if (element instanceof IResource) { resource = (IResource) element; } else if (element instanceof IAdaptable) { IAdaptable adaptable = (IAdaptable) element; resource = (IResource) adaptable.getAdapter(IResource.class); } if (resource != null && !resource.isDerived()) { if (resource.getType() != IResource.FILE) { return true; } String extension = resource.getFileExtension(); if (extension == null) { return true; } for (String extension2 : extensions) { if (extension.equalsIgnoreCase(extension2)) { return true; } } } return false; } } }