/******************************************************************************* * Copyright (c) 2000, 2015 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ui.internal.ide.dialogs; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; import org.eclipse.ui.dialogs.ISelectionStatusValidator; import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; /** * Selection dialog to select files and/or folders on the file system. Use * setInput to set input to an IFileStore that points to a folder. * * @since 2.1 */ public class FileFolderSelectionDialog extends ElementTreeSelectionDialog { /** * Label provider for IFileStore objects. */ private static class FileLabelProvider extends LabelProvider { private static final Image IMG_FOLDER = PlatformUI.getWorkbench() .getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER); private static final Image IMG_FILE = PlatformUI.getWorkbench() .getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE); @Override public Image getImage(Object element) { if (element instanceof IFileStore) { IFileStore curr = (IFileStore) element; if (curr.fetchInfo().isDirectory()) { return IMG_FOLDER; } return IMG_FILE; } return null; } @Override public String getText(Object element) { if (element instanceof IFileStore) { return ((IFileStore) element).getName(); } return super.getText(element); } } /** * Content provider for IFileStore objects. */ private static class FileContentProvider implements ITreeContentProvider { private static final Object[] EMPTY = new Object[0]; private IFileStoreFilter fileFilter; /** * Creates a new instance of the receiver. * * @param showFiles * <code>true</code> files and folders are returned by the * receiver. <code>false</code> only folders are returned. */ public FileContentProvider(final boolean showFiles) { fileFilter = file -> { if (!file.fetchInfo().isDirectory() && showFiles == false) { return false; } return true; }; } @Override public Object[] getChildren(Object parentElement) { if (parentElement instanceof IFileStore) { IFileStore[] children = IDEResourceInfoUtils.listFileStores( (IFileStore) parentElement, fileFilter, new NullProgressMonitor()); if (children != null) { return children; } } return EMPTY; } @Override public Object getParent(Object element) { if (element instanceof IFileStore) { return ((IFileStore) element).getParent(); } return null; } @Override public boolean hasChildren(Object element) { return getChildren(element).length > 0; } @Override public Object[] getElements(Object element) { return getChildren(element); } @Override public void dispose() { } @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } } /** * Viewer sorter that places folders first, then files. */ private static class FileViewerSorter extends ViewerComparator { @Override public int category(Object element) { if (element instanceof IFileStore && !((IFileStore) element).fetchInfo().isDirectory()) { return 1; } return 0; } } /** * Validates the selection based on the multi select and folder setting. */ private static class FileSelectionValidator implements ISelectionStatusValidator { private boolean multiSelect; private boolean acceptFolders; /** * Creates a new instance of the receiver. * * @param multiSelect * <code>true</code> if multi selection is allowed. * <code>false</code> if only single selection is allowed. * @param acceptFolders * <code>true</code> if folders can be selected in the * dialog. <code>false</code> only files and be selected. */ public FileSelectionValidator(boolean multiSelect, boolean acceptFolders) { this.multiSelect = multiSelect; this.acceptFolders = acceptFolders; } @Override public IStatus validate(Object[] selection) { int nSelected = selection.length; String pluginId = IDEWorkbenchPlugin.IDE_WORKBENCH; if (nSelected == 0 || (nSelected > 1 && multiSelect == false)) { return new Status(IStatus.ERROR, pluginId, IStatus.ERROR, IDEResourceInfoUtils.EMPTY_STRING, null); } for (Object currentSelection : selection) { if (currentSelection instanceof IFileStore) { IFileStore file = (IFileStore) currentSelection; if (acceptFolders == false && file.fetchInfo().isDirectory()) { return new Status(IStatus.ERROR, pluginId, IStatus.ERROR, IDEResourceInfoUtils.EMPTY_STRING, null); } } } // Return an ok status with no message as SelectionStatusDialog will display default ok message return new Status(IStatus.OK, pluginId, IDEResourceInfoUtils.EMPTY_STRING); } } /** * Creates a new instance of the receiver. * * @param parent * @param multiSelect * <code>true</code> if multi selection is allowed. * <code>false</code> if only single selection is allowed. * @param type * one or both of <code>IResource.FILE</code> and * <code>IResource.FOLDER</code>, ORed together. If * <code>IResource.FILE</code> is specified files and folders * are displayed in the dialog. Otherwise only folders are * displayed. If <code>IResource.FOLDER</code> is specified * folders can be selected in addition to files. */ public FileFolderSelectionDialog(Shell parent, boolean multiSelect, int type) { super(parent, new FileLabelProvider(), new FileContentProvider( (type & IResource.FILE) != 0)); setComparator(new FileViewerSorter()); setValidator(new FileSelectionValidator(multiSelect, (type & IResource.FOLDER) != 0)); setShellStyle(getShellStyle() | SWT.SHEET); } }