| /******************************************************************************* |
| * Copyright (c) 2011, 2015 Wind River Systems, Inc. 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: |
| * Wind River Systems - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.tcf.te.tcf.filesystem.ui.dialogs; |
| |
| import java.util.concurrent.atomic.AtomicInteger; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.jface.viewers.DecoratingLabelProvider; |
| import org.eclipse.jface.viewers.ILabelDecorator; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ITreeContentProvider; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.runtime.IFSTreeNode; |
| import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.runtime.IRuntimeModel; |
| import org.eclipse.tcf.te.tcf.filesystem.core.model.ModelManager; |
| import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin; |
| import org.eclipse.tcf.te.tcf.filesystem.ui.controls.FSTreeContentProvider; |
| import org.eclipse.tcf.te.tcf.filesystem.ui.controls.FSTreeViewerSorter; |
| import org.eclipse.tcf.te.tcf.filesystem.ui.interfaces.IFSConstants; |
| import org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.FSTreeElementLabelProvider; |
| import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages; |
| import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode; |
| import org.eclipse.tcf.te.ui.trees.FilterDescriptor; |
| import org.eclipse.tcf.te.ui.trees.Pending; |
| import org.eclipse.tcf.te.ui.trees.ViewerStateManager; |
| import org.eclipse.ui.IDecoratorManager; |
| import org.eclipse.ui.IWorkbench; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; |
| import org.eclipse.ui.dialogs.ISelectionStatusValidator; |
| |
| |
| /** |
| * File system open file dialog. |
| */ |
| public class FSOpenFileDialog extends ElementTreeSelectionDialog { |
| private String filterPath = null; |
| /* default */ TreeViewer viewer = null; |
| |
| /** |
| * Create an FSFolderSelectionDialog using the specified shell as the parent. |
| * |
| * @param parentShell The parent shell. |
| */ |
| public FSOpenFileDialog(Shell parentShell) { |
| this(parentShell, new FSTreeElementLabelProvider(), new FSTreeContentProvider()); |
| } |
| |
| /** |
| * Create an FSFolderSelectionDialog using the specified shell, an FSTreeLabelProvider, and a |
| * content provider that provides the tree nodes. |
| * |
| * @param parentShell The parent shell. |
| * @param labelProvider The label provider. |
| * @param contentProvider The content provider. |
| */ |
| private FSOpenFileDialog(Shell parentShell, ILabelProvider labelProvider, ITreeContentProvider contentProvider) { |
| super(parentShell, createDecoratingLabelProvider(labelProvider), contentProvider); |
| setTitle(Messages.FSOpenFileDialog_title); |
| setMessage(Messages.FSOpenFileDialog_message); |
| this.setAllowMultiple(false); |
| this.setStatusLineAboveButtons(false); |
| this.setComparator(new FSTreeViewerSorter()); |
| this.setValidator(new ISelectionStatusValidator() { |
| @Override |
| public IStatus validate(Object[] selection) { |
| return isValidSelection(selection); |
| } |
| }); |
| } |
| |
| /** |
| * Sets the filter path. |
| * |
| * @param filterPath The filter path or <code>null</code>. |
| */ |
| public void setFilterPath(String filterPath) { |
| this.filterPath = filterPath; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.ui.dialogs.ElementTreeSelectionDialog#setInput(java.lang.Object) |
| */ |
| @Override |
| public void setInput(Object input) { |
| super.setInput(input); |
| FilterDescriptor[] filterDescriptors = ViewerStateManager.getInstance().getFilterDescriptors(IFSConstants.ID_TREE_VIEWER_FS, input); |
| Assert.isNotNull(filterDescriptors); |
| for (FilterDescriptor descriptor : filterDescriptors) { |
| if (descriptor.isEnabled()) { |
| addFilter(descriptor.getFilter()); |
| } |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.dialogs.ElementTreeSelectionDialog#create() |
| */ |
| @Override |
| public void create() { |
| super.create(); |
| |
| if (filterPath != null && !"".equals(filterPath.trim())) { //$NON-NLS-1$ |
| IPath path = new Path(filterPath); |
| if (viewer.getInput() instanceof IPeerNode) { |
| Object element = null; |
| IRuntimeModel model = ModelManager.getRuntimeModel((IPeerNode)viewer.getInput()); |
| if (model != null) { |
| IFSTreeNode root = model.getRoot(); |
| ITreeContentProvider contentProvider = (ITreeContentProvider)viewer.getContentProvider(); |
| Object[] elements = contentProvider.getElements(root); |
| String segment = path.getDevice() != null ? path.getDevice() : path.segmentCount() > 0 ? path.segment(0) : null; |
| if (segment != null) { |
| for (Object elem : elements) { |
| if (!(elem instanceof IFSTreeNode)) break; |
| IFSTreeNode child = (IFSTreeNode)elem; |
| String name = child.getName(); |
| if (name.endsWith("\\") || name.endsWith("/")) name = name.substring(0, name.length() - 1); //$NON-NLS-1$ //$NON-NLS-2$ |
| boolean matches = child.isWindowsNode() ? name.equalsIgnoreCase(segment) : name.equals(segment); |
| if (matches) { |
| if (path.segmentCount() > (path.getDevice() != null ? 0 : 1)) { |
| // Have to drill down a bit further |
| element = findRecursive(child, path, path.getDevice() != null ? 0 : 1); |
| if (element != null) break; |
| } else { |
| element = child; |
| break; |
| } |
| } |
| } |
| } |
| } |
| |
| if (element != null) { |
| final ISelection selection = new StructuredSelection(element); |
| final AtomicInteger counter = new AtomicInteger(); |
| |
| Runnable runnable = new Runnable() { |
| @Override |
| public void run() { |
| viewer.setSelection(selection, true); |
| if (!selection.equals(viewer.getSelection())) { |
| if (counter.incrementAndGet() <= 10) { |
| viewer.getControl().getDisplay().asyncExec(this); |
| } |
| } |
| } |
| }; |
| |
| viewer.getControl().getDisplay().asyncExec(runnable); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Finds the given path within the file system hierarchy. |
| * |
| * @param parent The parent file system node. Must not be <code>null</code>. |
| * @param path The path. Must not be <code>null</code>. |
| * @param index The segment index. |
| * |
| * @return The matching file system node or <code>null</code>. |
| */ |
| private IFSTreeNode findRecursive(IFSTreeNode parent, IPath path, int index) { |
| Assert.isNotNull(parent); |
| Assert.isNotNull(path); |
| |
| IFSTreeNode node = null; |
| |
| ITreeContentProvider contentProvider = (ITreeContentProvider)viewer.getContentProvider(); |
| Object[] elements = contentProvider.getElements(parent); |
| while (elements.length == 1 && elements[0] instanceof Pending) { |
| try { |
| Thread.sleep(100); |
| } catch (InterruptedException e) {} |
| elements = contentProvider.getElements(parent); |
| } |
| |
| String segment = path.segment(index); |
| |
| for (Object element : elements) { |
| if (!(element instanceof IFSTreeNode)) break; |
| IFSTreeNode child = (IFSTreeNode)element; |
| String name = child.getName(); |
| if (name.endsWith("\\") || name.endsWith("/")) name = name.substring(0, name.length() - 1); //$NON-NLS-1$ //$NON-NLS-2$ |
| boolean matches = child.isWindowsNode() ? name.equalsIgnoreCase(segment) : name.equals(segment); |
| if (matches) { |
| if (path.segmentCount() > index + 1) { |
| // Have to drill down a bit further |
| node = findRecursive(child, path, index + 1); |
| if (node != null) break; |
| } else { |
| node = child; |
| break; |
| } |
| } |
| } |
| |
| return node; |
| } |
| |
| /** |
| * Create a decorating label provider using the specified label provider. |
| * |
| * @param labelProvider The label provider that actually provides labels and images. |
| * @return The decorating label provider. |
| */ |
| private static ILabelProvider createDecoratingLabelProvider(ILabelProvider labelProvider) { |
| IWorkbench workbench = PlatformUI.getWorkbench(); |
| IDecoratorManager manager = workbench.getDecoratorManager(); |
| ILabelDecorator decorator = manager.getLabelDecorator(); |
| return new DecoratingLabelProvider(labelProvider,decorator); |
| } |
| |
| /** |
| * Create the tree viewer and set it to the label provider. |
| */ |
| @Override |
| protected TreeViewer doCreateTreeViewer(Composite parent, int style) { |
| viewer = super.doCreateTreeViewer(parent, style); |
| viewer.getTree().setLinesVisible(false); |
| return viewer; |
| } |
| |
| /** |
| * If the specified selection is a valid folder to be selected. |
| * |
| * @param selection The selected folders. |
| * @return An error status if it is invalid or an OK status indicating it is valid. |
| */ |
| IStatus isValidSelection(Object[] selection) { |
| String pluginId = UIPlugin.getUniqueIdentifier(); |
| IStatus error = new Status(IStatus.ERROR, pluginId, null); |
| if (selection == null || selection.length == 0) { |
| return error; |
| } |
| if (!(selection[0] instanceof IFSTreeNode)) { |
| return error; |
| } |
| IFSTreeNode target = (IFSTreeNode) selection[0]; |
| if(!target.isFile()) { |
| return error; |
| } |
| return new Status(IStatus.OK, pluginId, null); |
| } |
| } |