diff options
Diffstat (limited to 'target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/FSOpenFileDialog.java')
-rw-r--r-- | target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/FSOpenFileDialog.java | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/FSOpenFileDialog.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/FSOpenFileDialog.java new file mode 100644 index 000000000..5b2629c27 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/FSOpenFileDialog.java @@ -0,0 +1,263 @@ +/******************************************************************************* + * Copyright (c) 2011, 2014 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.IRuntimeModel; +import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode; +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) { + FSTreeNode 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 FSTreeNode)) break; + FSTreeNode child = (FSTreeNode)elem; + String name = child.name; + 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 FSTreeNode findRecursive(FSTreeNode parent, IPath path, int index) { + Assert.isNotNull(parent); + Assert.isNotNull(path); + + FSTreeNode 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 FSTreeNode)) break; + FSTreeNode child = (FSTreeNode)element; + String name = child.name; + 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 FSTreeNode)) { + return error; + } + FSTreeNode target = (FSTreeNode) selection[0]; + if(!target.isFile()) { + return error; + } + return new Status(IStatus.OK, pluginId, null); + } +} |