mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 01:15:29 +02:00
[396334] - Fix new folder button so that it actually creates a new
folder. Also, move resource browser to a separate widget so that it can be embedded in other controls. Signed-off-by: Greg Watson <g.watson@computer.org>
This commit is contained in:
parent
5b62b88dee
commit
c90aeb7d2c
12 changed files with 1751 additions and 398 deletions
|
@ -31,27 +31,33 @@ import org.eclipse.ui.model.IWorkbenchAdapter;
|
|||
import org.eclipse.ui.progress.IDeferredWorkbenchAdapter;
|
||||
import org.eclipse.ui.progress.IElementCollector;
|
||||
|
||||
public class DeferredFileStore implements IDeferredWorkbenchAdapter {
|
||||
public class DeferredFileStore implements IDeferredWorkbenchAdapter, IAdaptable {
|
||||
private final IFileStore fFileStore;
|
||||
private IFileInfo fFileInfo;
|
||||
private IFileInfo fTargetInfo;
|
||||
private ImageDescriptor fImage;
|
||||
private final boolean fExcludeHidden;
|
||||
private final DeferredFileStore fParent;
|
||||
|
||||
/**
|
||||
* @since 7.0
|
||||
*/
|
||||
public DeferredFileStore(IFileStore store, boolean exclude) {
|
||||
this(store, null, exclude);
|
||||
this(store, null, exclude, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 7.0
|
||||
*/
|
||||
public DeferredFileStore(IFileStore store, IFileInfo info, boolean exclude) {
|
||||
public DeferredFileStore(IFileStore store, boolean exclude, DeferredFileStore parent) {
|
||||
this(store, null, exclude, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 7.0
|
||||
*/
|
||||
public DeferredFileStore(IFileStore store, IFileInfo info, boolean exclude, DeferredFileStore parent) {
|
||||
fFileStore = store;
|
||||
fFileInfo = info;
|
||||
fExcludeHidden = exclude;
|
||||
fParent = parent;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -60,13 +66,14 @@ public class DeferredFileStore implements IDeferredWorkbenchAdapter {
|
|||
* @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#fetchDeferredChildren(java.lang.Object,
|
||||
* org.eclipse.ui.progress.IElementCollector, org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
@Override
|
||||
public void fetchDeferredChildren(Object object, IElementCollector collector, IProgressMonitor monitor) {
|
||||
ArrayList<DeferredFileStore> children = new ArrayList<DeferredFileStore>();
|
||||
try {
|
||||
IFileInfo[] childInfos = fFileStore.childInfos(EFS.NONE, monitor);
|
||||
for (IFileInfo info : childInfos) {
|
||||
if (!(fExcludeHidden && info.getName().startsWith("."))) { //$NON-NLS-1$
|
||||
children.add(new DeferredFileStore(fFileStore.getChild(info.getName()), info, fExcludeHidden));
|
||||
children.add(new DeferredFileStore(fFileStore.getChild(info.getName()), info, fExcludeHidden, this));
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
|
@ -75,6 +82,7 @@ public class DeferredFileStore implements IDeferredWorkbenchAdapter {
|
|||
if (children != null) {
|
||||
collector.add(children.toArray(), monitor);
|
||||
}
|
||||
collector.done();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,6 +107,15 @@ public class DeferredFileStore implements IDeferredWorkbenchAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public Object getAdapter(Class adapter) {
|
||||
if (IWorkbenchAdapter.class.equals(adapter)) {
|
||||
return this;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the IWorkbenchAdapter for element or the element if it is
|
||||
* an instance of IWorkbenchAdapter. If it does not exist return
|
||||
|
@ -111,58 +128,6 @@ public class DeferredFileStore implements IDeferredWorkbenchAdapter {
|
|||
return (IWorkbenchAdapter) getAdapter(element, IWorkbenchAdapter.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.model.IWorkbenchAdapter#getChildren(java.lang.Object)
|
||||
*/
|
||||
public Object[] getChildren(Object o) {
|
||||
try {
|
||||
IFileStore[] stores = fFileStore.childStores(EFS.NONE, null);
|
||||
List<DeferredFileStore> def = new ArrayList<DeferredFileStore>();
|
||||
for (int i = 0; i < stores.length; i++) {
|
||||
if (!(fExcludeHidden && stores[i].getName().startsWith("."))) { //$NON-NLS-1$
|
||||
def.add(new DeferredFileStore(stores[i], fExcludeHidden));
|
||||
}
|
||||
}
|
||||
return def.toArray();
|
||||
} catch (CoreException e) {
|
||||
return new Object[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filestore backing this object
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public IFileStore getFileStore() {
|
||||
return fFileStore;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.model.IWorkbenchAdapter#getImageDescriptor(java.lang.Object)
|
||||
*/
|
||||
public ImageDescriptor getImageDescriptor(Object object) {
|
||||
fetchInfo();
|
||||
if (fImage == null) {
|
||||
boolean isDir = fFileInfo.isDirectory() || (fTargetInfo != null && fTargetInfo.isDirectory());
|
||||
FileSystemElement element = new FileSystemElement(fFileStore.getName(), null, isDir);
|
||||
IWorkbenchAdapter adapter = getAdapter(element);
|
||||
if (adapter != null) {
|
||||
ImageDescriptor imageDesc = adapter.getImageDescriptor(object);
|
||||
if (fTargetInfo != null) {
|
||||
imageDesc = new OverlayImageDescriptor(imageDesc, RemoteUIImages.DESC_OVR_SYMLINK,
|
||||
OverlayImageDescriptor.BOTTOM_RIGHT);
|
||||
}
|
||||
fImage = imageDesc;
|
||||
}
|
||||
}
|
||||
return fImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* If it is possible to adapt the given object to the given type, this returns the adapter. Performs the following checks:
|
||||
*
|
||||
|
@ -212,11 +177,66 @@ public class DeferredFileStore implements IDeferredWorkbenchAdapter {
|
|||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.model.IWorkbenchAdapter#getChildren(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Object[] getChildren(Object o) {
|
||||
try {
|
||||
IFileStore[] stores = fFileStore.childStores(EFS.NONE, null);
|
||||
List<DeferredFileStore> def = new ArrayList<DeferredFileStore>();
|
||||
for (int i = 0; i < stores.length; i++) {
|
||||
if (!(fExcludeHidden && stores[i].getName().startsWith("."))) { //$NON-NLS-1$
|
||||
def.add(new DeferredFileStore(stores[i], fExcludeHidden, this));
|
||||
}
|
||||
}
|
||||
return def.toArray();
|
||||
} catch (CoreException e) {
|
||||
return new Object[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filestore backing this object
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public IFileStore getFileStore() {
|
||||
return fFileStore;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.model.IWorkbenchAdapter#getImageDescriptor(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public ImageDescriptor getImageDescriptor(Object object) {
|
||||
fetchInfo();
|
||||
if (fImage == null) {
|
||||
boolean isDir = fFileInfo.isDirectory() || (fTargetInfo != null && fTargetInfo.isDirectory());
|
||||
FileSystemElement element = new FileSystemElement(fFileStore.getName(), null, isDir);
|
||||
IWorkbenchAdapter adapter = getAdapter(element);
|
||||
if (adapter != null) {
|
||||
ImageDescriptor imageDesc = adapter.getImageDescriptor(object);
|
||||
if (fTargetInfo != null) {
|
||||
imageDesc = new OverlayImageDescriptor(imageDesc, RemoteUIImages.DESC_OVR_SYMLINK,
|
||||
OverlayImageDescriptor.BOTTOM_RIGHT);
|
||||
}
|
||||
fImage = imageDesc;
|
||||
}
|
||||
}
|
||||
return fImage;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.model.IWorkbenchAdapter#getLabel(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public String getLabel(Object o) {
|
||||
return fFileStore.getName();
|
||||
}
|
||||
|
@ -226,8 +246,9 @@ public class DeferredFileStore implements IDeferredWorkbenchAdapter {
|
|||
*
|
||||
* @see org.eclipse.ui.model.IWorkbenchAdapter#getParent(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Object getParent(Object o) {
|
||||
return fFileStore.getParent();
|
||||
return fParent;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -235,6 +256,7 @@ public class DeferredFileStore implements IDeferredWorkbenchAdapter {
|
|||
*
|
||||
* @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#getRule(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public ISchedulingRule getRule(Object object) {
|
||||
return null;
|
||||
}
|
||||
|
@ -244,6 +266,7 @@ public class DeferredFileStore implements IDeferredWorkbenchAdapter {
|
|||
*
|
||||
* @see org.eclipse.ui.progress.IDeferredWorkbenchAdapter#isContainer()
|
||||
*/
|
||||
@Override
|
||||
public boolean isContainer() {
|
||||
fetchInfo();
|
||||
return fFileInfo.isDirectory() || (fTargetInfo != null && fTargetInfo.isDirectory());
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2013 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.remote.internal.ui;
|
||||
|
||||
import org.eclipse.jface.viewers.IElementComparer;
|
||||
|
||||
public class DeferredFileStoreComparer implements IElementComparer {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.IElementComparer#equals(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o1, Object o2) {
|
||||
if (o1 == o2) {
|
||||
return true;
|
||||
}
|
||||
if (o1 == null) {
|
||||
return false; // o2 != null if we reach this point
|
||||
}
|
||||
if (o1.equals(o2)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Assume they are DeferredFileStore
|
||||
DeferredFileStore c1 = (o1 instanceof DeferredFileStore) ? (DeferredFileStore) o1 : null;
|
||||
DeferredFileStore c2 = (o2 instanceof DeferredFileStore) ? (DeferredFileStore) o2 : null;
|
||||
if (c1 == null || c2 == null) {
|
||||
return false;
|
||||
}
|
||||
return c1.getFileStore().equals(c2.getFileStore());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.IElementComparer#hashCode(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public int hashCode(Object element) {
|
||||
if (element instanceof DeferredFileStore) {
|
||||
return ((DeferredFileStore) element).getFileStore().hashCode();
|
||||
}
|
||||
return element.hashCode();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2003, 2009 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.remote.internal.ui;
|
||||
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.jface.resource.ImageDescriptor;
|
||||
import org.eclipse.remote.internal.ui.messages.Messages;
|
||||
import org.eclipse.ui.model.IWorkbenchAdapter;
|
||||
|
||||
/**
|
||||
* The PendingUpdateAdapter is a convenience object that can be used
|
||||
* by a BaseWorkbenchContentProvider that wants to show a pending update.
|
||||
*/
|
||||
public class PendingUpdateAdapter implements IWorkbenchAdapter, IAdaptable {
|
||||
|
||||
boolean removed = false;
|
||||
|
||||
/**
|
||||
* Return whether or not this has been removed from the tree.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isRemoved() {
|
||||
return removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not this has been removed from the tree.
|
||||
*
|
||||
* @param removedValue
|
||||
* boolean
|
||||
*/
|
||||
public void setRemoved(boolean removedValue) {
|
||||
this.removed = removedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the receiver.
|
||||
*/
|
||||
public PendingUpdateAdapter() {
|
||||
// No initial behavior
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Object getAdapter(Class adapter) {
|
||||
if (adapter == IWorkbenchAdapter.class) {
|
||||
return this;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.model.IWorkbenchAdapter#getChildren(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Object[] getChildren(Object o) {
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.model.IWorkbenchAdapter#getImageDescriptor(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public ImageDescriptor getImageDescriptor(Object object) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.model.IWorkbenchAdapter#getLabel(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public String getLabel(Object o) {
|
||||
return Messages.PendingUpdateAdapter_Pending;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.model.IWorkbenchAdapter#getParent(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Object getParent(Object o) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -10,39 +10,44 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.ui;
|
||||
|
||||
import org.eclipse.jface.viewers.AbstractTreeViewer;
|
||||
import org.eclipse.jface.viewers.Viewer;
|
||||
import org.eclipse.ui.IWorkingSet;
|
||||
import org.eclipse.ui.model.WorkbenchContentProvider;
|
||||
import org.eclipse.ui.progress.DeferredTreeContentManager;
|
||||
|
||||
/**
|
||||
* Extension to the generic workbench content provider mechanism
|
||||
* to lazily determine whether an element has children. That is,
|
||||
* to lazily determine whether an element has children. That is,
|
||||
* children for an element aren't fetched until the user clicks
|
||||
* on the tree expansion box.
|
||||
*/
|
||||
public class RemoteContentProvider extends WorkbenchContentProvider {
|
||||
private IWorkingSet workingSet;
|
||||
private DeferredTreeContentManager manager;
|
||||
private RemoteTreeContentManager manager;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object,
|
||||
* java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
|
||||
if (newInput != null) {
|
||||
manager = new DeferredTreeContentManager((AbstractTreeViewer) viewer);
|
||||
manager = new RemoteTreeContentManager(this, (RemoteTreeViewer) viewer, null);
|
||||
} else {
|
||||
manager = null;
|
||||
}
|
||||
super.inputChanged(viewer, oldInput, newInput);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.model.BaseWorkbenchContentProvider#hasChildren(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean hasChildren(Object element) {
|
||||
if (manager != null && manager.isDeferredAdapter(element)) {
|
||||
if (manager != null /* && manager.isDeferredAdapter(element) */) {
|
||||
return manager.mayHaveChildren(element);
|
||||
}
|
||||
|
||||
|
@ -51,7 +56,9 @@ public class RemoteContentProvider extends WorkbenchContentProvider {
|
|||
|
||||
/**
|
||||
* Sets the workingSet.
|
||||
* @param workingSet The workingSet to set
|
||||
*
|
||||
* @param workingSet
|
||||
* The workingSet to set
|
||||
*/
|
||||
public void setWorkingSet(IWorkingSet workingSet) {
|
||||
this.workingSet = workingSet;
|
||||
|
@ -59,15 +66,19 @@ public class RemoteContentProvider extends WorkbenchContentProvider {
|
|||
|
||||
/**
|
||||
* Returns the workingSet.
|
||||
*
|
||||
* @return IWorkingSet
|
||||
*/
|
||||
public IWorkingSet getWorkingSet() {
|
||||
return workingSet;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.model.WorkbenchContentProvider#getChildren(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Object[] getChildren(Object element) {
|
||||
if (manager != null) {
|
||||
Object[] children = manager.getChildren(element);
|
||||
|
|
|
@ -10,35 +10,39 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.remote.internal.ui;
|
||||
|
||||
|
||||
import org.eclipse.core.filesystem.IFileInfo;
|
||||
import org.eclipse.jface.viewers.Viewer;
|
||||
import org.eclipse.jface.viewers.ViewerComparator;
|
||||
|
||||
public class RemoteResourceComparator extends ViewerComparator {
|
||||
|
||||
|
||||
private boolean ascending = true;
|
||||
|
||||
|
||||
public RemoteResourceComparator() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
public void setAscending(boolean ascending) {
|
||||
this.ascending = ascending;
|
||||
}
|
||||
|
||||
|
||||
public boolean isAscending() {
|
||||
return ascending;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public int compare(Viewer viewer, Object o1, Object o2) {
|
||||
if (o1 instanceof IFileInfo && o2 instanceof IFileInfo) {
|
||||
int compareResult = ((IFileInfo)o1).getName().compareToIgnoreCase(((IFileInfo)o2).getName());;
|
||||
int compareResult = ((IFileInfo) o1).getName().compareToIgnoreCase(((IFileInfo) o2).getName());
|
||||
return ascending ? compareResult : -compareResult;
|
||||
}
|
||||
|
||||
|
||||
return super.compare(viewer, o1, o2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,384 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2008 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.remote.internal.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.jface.viewers.ITreeContentProvider;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.ui.IWorkbenchPartSite;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.eclipse.ui.progress.IDeferredWorkbenchAdapter;
|
||||
import org.eclipse.ui.progress.IElementCollector;
|
||||
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
|
||||
import org.eclipse.ui.progress.WorkbenchJob;
|
||||
|
||||
/**
|
||||
* A remote content manager that merges content into a tree rather then replacing its children with a
|
||||
* "pending" node, and then the real children when they are available. This avoids collapsing the viewer when
|
||||
* a refresh is performed. This implementation is currently tied to the <code>RemoteTreeViewer</code>.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
public class RemoteTreeContentManager {
|
||||
private final RemoteTreeViewer fViewer;
|
||||
private IWorkbenchSiteProgressService progressService;
|
||||
|
||||
/**
|
||||
* Job to fetch children
|
||||
*/
|
||||
private final Job fFetchJob = new FetchJob();
|
||||
|
||||
/**
|
||||
* Queue of parents to fetch children for, and associated element collectors and deferred adapters.
|
||||
*/
|
||||
private final List<Object> fElementQueue = new ArrayList<Object>();
|
||||
private final List<IElementCollector> fCollectors = new ArrayList<IElementCollector>();
|
||||
private final List<IDeferredWorkbenchAdapter> fAdapaters = new ArrayList<IDeferredWorkbenchAdapter>();
|
||||
|
||||
/**
|
||||
* Fetching children is done in a single background job. This makes fetching single threaded/serial per
|
||||
* view.
|
||||
*/
|
||||
private class FetchJob extends Job {
|
||||
|
||||
public FetchJob() {
|
||||
super("FetchJob"); //$NON-NLS-1$
|
||||
setSystem(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
while (!fElementQueue.isEmpty() && !monitor.isCanceled()) {
|
||||
Object element = null;
|
||||
IElementCollector collector = null;
|
||||
IDeferredWorkbenchAdapter adapter = null;
|
||||
synchronized (fElementQueue) {
|
||||
// could have been cancelled after entering the while loop
|
||||
if (fElementQueue.isEmpty()) {
|
||||
return Status.CANCEL_STATUS;
|
||||
}
|
||||
element = fElementQueue.remove(0);
|
||||
collector = fCollectors.remove(0);
|
||||
adapter = fAdapaters.remove(0);
|
||||
}
|
||||
adapter.fetchDeferredChildren(element, collector, monitor);
|
||||
}
|
||||
if (monitor.isCanceled()) {
|
||||
return Status.CANCEL_STATUS;
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Element collector
|
||||
*/
|
||||
private class Collector implements IElementCollector {
|
||||
// number of children added to the tree
|
||||
int offset = 0;
|
||||
Object fParent;
|
||||
|
||||
public Collector(Object parent) {
|
||||
fParent = parent;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.progress.IElementCollector#add(java.lang.Object,
|
||||
* org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
@Override
|
||||
public void add(Object element, IProgressMonitor monitor) {
|
||||
add(new Object[] { element }, monitor);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.progress.IElementCollector#add(java.lang.Object[],
|
||||
* org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
@Override
|
||||
public void add(Object[] elements, IProgressMonitor monitor) {
|
||||
Object[] filtered = fViewer.filter(elements);
|
||||
if (fViewer.getComparator() != null) {
|
||||
fViewer.getComparator().sort(fViewer, filtered);
|
||||
}
|
||||
if (filtered.length > 0) {
|
||||
replaceChildren(fParent, filtered, offset, monitor);
|
||||
offset = offset + filtered.length;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.progress.IElementCollector#done()
|
||||
*/
|
||||
@Override
|
||||
public void done() {
|
||||
prune(fParent, offset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Contructs a new content manager.
|
||||
*
|
||||
* @param provider
|
||||
* content provider
|
||||
* @param viewer
|
||||
* viewer
|
||||
* @param site
|
||||
* part site
|
||||
*/
|
||||
public RemoteTreeContentManager(ITreeContentProvider provider, RemoteTreeViewer viewer, IWorkbenchPartSite site) {
|
||||
fViewer = viewer;
|
||||
if (site != null) {
|
||||
Object siteService = site.getAdapter(IWorkbenchSiteProgressService.class);
|
||||
if (siteService != null) {
|
||||
progressService = (IWorkbenchSiteProgressService) siteService;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the element collector for the receiver.
|
||||
*
|
||||
* @param parent
|
||||
* The parent object being filled in,
|
||||
* @param placeholder
|
||||
* The adapter that will be used to indicate that results are pending, possibly <code>null</code>
|
||||
* @return IElementCollector
|
||||
*/
|
||||
protected IElementCollector createElementCollector(Object parent, PendingUpdateAdapter placeholder) {
|
||||
return new Collector(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the child elements of the given element, or in the case of a deferred element, returns a
|
||||
* placeholder. If a deferred element is used, a job is created to fetch the children in the background.
|
||||
*
|
||||
* @param parent
|
||||
* The parent object.
|
||||
* @return Object[] or <code>null</code> if parent is not an instance of IDeferredWorkbenchAdapter.
|
||||
*/
|
||||
public Object[] getChildren(final Object parent) {
|
||||
IDeferredWorkbenchAdapter element = getAdapter(parent);
|
||||
if (element == null) {
|
||||
return null;
|
||||
}
|
||||
Object[] currentChildren = fViewer.getCurrentChildren(parent);
|
||||
PendingUpdateAdapter placeholder = null;
|
||||
if (currentChildren == null || currentChildren.length == 0) {
|
||||
placeholder = new PendingUpdateAdapter();
|
||||
}
|
||||
startFetchingDeferredChildren(parent, element, placeholder);
|
||||
if (placeholder == null) {
|
||||
return currentChildren;
|
||||
}
|
||||
return new Object[] { placeholder };
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a UIJob to replace the children of the parent in the tree viewer.
|
||||
*
|
||||
* @param parent
|
||||
* the parent for which children are to be replaced
|
||||
* @param children
|
||||
* the replacement children
|
||||
* @param offset
|
||||
* the offset at which to start replacing children
|
||||
* @param monitor
|
||||
* progress monitor
|
||||
*/
|
||||
protected void replaceChildren(final Object parent, final Object[] children, final int offset, IProgressMonitor monitor) {
|
||||
if (monitor.isCanceled()) {
|
||||
return;
|
||||
}
|
||||
WorkbenchJob updateJob = new WorkbenchJob("IncrementalDeferredTreeContentManager") { //$NON-NLS-1$
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
@Override
|
||||
public IStatus runInUIThread(IProgressMonitor updateMonitor) {
|
||||
// Cancel the job if the tree viewer got closed
|
||||
if (fViewer.getControl().isDisposed()) {
|
||||
return Status.CANCEL_STATUS;
|
||||
}
|
||||
fViewer.replace(parent, children, offset);
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
updateJob.setSystem(true);
|
||||
updateJob.setPriority(Job.INTERACTIVE);
|
||||
updateJob.schedule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a UIJob to prune the children of the parent in the tree viewer, starting at the given offset.
|
||||
*
|
||||
* @param parent
|
||||
* the parent for which children should be pruned
|
||||
* @param offset
|
||||
* the offset at which children should be pruned. All children at and after this index will be
|
||||
* removed from the tree.
|
||||
*/
|
||||
protected void prune(final Object parent, final int offset) {
|
||||
WorkbenchJob updateJob = new WorkbenchJob("DeferredTree") { //$NON-NLS-1$
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
@Override
|
||||
public IStatus runInUIThread(IProgressMonitor updateMonitor) {
|
||||
// Cancel the job if the tree viewer got closed
|
||||
if (fViewer.getControl().isDisposed()) {
|
||||
return Status.CANCEL_STATUS;
|
||||
}
|
||||
fViewer.prune(parent, offset);
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
updateJob.setSystem(true);
|
||||
updateJob.setPriority(Job.INTERACTIVE);
|
||||
updateJob.schedule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a job to clear the placeholder. This is used when the update for the tree is complete so that the
|
||||
* user is aware that no more updates are pending.
|
||||
*
|
||||
* @param placeholder
|
||||
*/
|
||||
protected void runClearPlaceholderJob(final PendingUpdateAdapter placeholder) {
|
||||
if (placeholder == null || placeholder.isRemoved() || !PlatformUI.isWorkbenchRunning()) {
|
||||
return;
|
||||
}
|
||||
// Clear the placeholder if it is still there
|
||||
WorkbenchJob clearJob = new WorkbenchJob("DeferredTreeContentManager_ClearJob") { //$NON-NLS-1$
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
@Override
|
||||
public IStatus runInUIThread(IProgressMonitor monitor) {
|
||||
if (!placeholder.isRemoved()) {
|
||||
Control control = fViewer.getControl();
|
||||
if (control.isDisposed()) {
|
||||
return Status.CANCEL_STATUS;
|
||||
}
|
||||
fViewer.remove(placeholder);
|
||||
placeholder.setRemoved(true);
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
clearJob.setSystem(true);
|
||||
clearJob.schedule();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.progress.DeferredTreeContentManager#getFetchJobName(java.lang.Object,
|
||||
* org.eclipse.ui.progress.IDeferredWorkbenchAdapter)
|
||||
*/
|
||||
protected String getFetchJobName(Object parent, IDeferredWorkbenchAdapter adapter) {
|
||||
return "RemoteTreeContentManager"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the IDeferredWorkbenchAdapter for element or the element if it is an instance of
|
||||
* IDeferredWorkbenchAdapter. If it does not exist return null.
|
||||
*
|
||||
* @param element
|
||||
* @return IDeferredWorkbenchAdapter or <code>null</code>
|
||||
*/
|
||||
protected IDeferredWorkbenchAdapter getAdapter(Object element) {
|
||||
if (element instanceof IDeferredWorkbenchAdapter) {
|
||||
return (IDeferredWorkbenchAdapter) element;
|
||||
}
|
||||
if (!(element instanceof IAdaptable)) {
|
||||
return null;
|
||||
}
|
||||
Object adapter = ((IAdaptable) element).getAdapter(IDeferredWorkbenchAdapter.class);
|
||||
if (adapter == null) {
|
||||
return null;
|
||||
}
|
||||
return (IDeferredWorkbenchAdapter) adapter;
|
||||
}
|
||||
|
||||
protected void startFetchingDeferredChildren(final Object parent, final IDeferredWorkbenchAdapter adapter,
|
||||
PendingUpdateAdapter placeholder) {
|
||||
final IElementCollector collector = createElementCollector(parent, placeholder);
|
||||
synchronized (fElementQueue) {
|
||||
if (!fElementQueue.contains(parent)) {
|
||||
fElementQueue.add(parent);
|
||||
fCollectors.add(collector);
|
||||
fAdapaters.add(adapter);
|
||||
}
|
||||
}
|
||||
if (progressService == null) {
|
||||
fFetchJob.schedule();
|
||||
} else {
|
||||
progressService.schedule(fFetchJob);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides an optimized lookup for determining if an element has children. This is required because
|
||||
* elements that are populated lazilly can't answer <code>getChildren</code> just to determine the
|
||||
* potential for children. Throw an AssertionFailedException if element is null.
|
||||
*
|
||||
* @param element
|
||||
* The Object being tested. This should not be <code>null</code>.
|
||||
* @return boolean <code>true</code> if there are potentially children.
|
||||
* @throws RuntimeException
|
||||
* if the element is null.
|
||||
*/
|
||||
public boolean mayHaveChildren(Object element) {
|
||||
// Assert.isNotNull(element, ProgressMessages.DeferredTreeContentManager_NotDeferred);
|
||||
IDeferredWorkbenchAdapter adapter = getAdapter(element);
|
||||
return adapter != null && adapter.isContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels any content this provider is currently fetching.
|
||||
*/
|
||||
public void cancel() {
|
||||
synchronized (fElementQueue) {
|
||||
fFetchJob.cancel();
|
||||
fElementQueue.clear();
|
||||
fAdapaters.clear();
|
||||
fCollectors.clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,451 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2008 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.remote.internal.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.jface.viewers.TreeViewer;
|
||||
import org.eclipse.swt.events.DisposeEvent;
|
||||
import org.eclipse.swt.events.DisposeListener;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Item;
|
||||
import org.eclipse.swt.widgets.Tree;
|
||||
import org.eclipse.swt.widgets.TreeItem;
|
||||
import org.eclipse.swt.widgets.Widget;
|
||||
import org.eclipse.ui.model.IWorkbenchAdapter;
|
||||
import org.eclipse.ui.progress.UIJob;
|
||||
|
||||
public class RemoteTreeViewer extends TreeViewer {
|
||||
private ExpansionJob fExpansionJob = null;
|
||||
private SelectionJob fSelectionJob = null;
|
||||
|
||||
private class ExpansionJob extends UIJob {
|
||||
|
||||
private Object element;
|
||||
private final List<Object> parents = new ArrayList<Object>(); // top down
|
||||
|
||||
/**
|
||||
* Constructs a job to expand the given element.
|
||||
*
|
||||
*/
|
||||
public ExpansionJob() {
|
||||
super("Expansion"); //$NON-NLS-1$
|
||||
setPriority(Job.INTERACTIVE);
|
||||
setSystem(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
@Override
|
||||
public IStatus runInUIThread(IProgressMonitor monitor) {
|
||||
if (getControl().isDisposed() || element == null) {
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
synchronized (RemoteTreeViewer.this) {
|
||||
boolean allParentsExpanded = true;
|
||||
Iterator<Object> iterator = parents.iterator();
|
||||
while (iterator.hasNext() && !monitor.isCanceled()) {
|
||||
Object parent = iterator.next();
|
||||
Widget item = findItem(parent);
|
||||
if (item != null) {
|
||||
expandToLevel(parent, 1);
|
||||
} else {
|
||||
allParentsExpanded = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allParentsExpanded) {
|
||||
Widget item = findItem(element);
|
||||
if (item != null) {
|
||||
if (isExpandable(element)) {
|
||||
expandToLevel(element, 1);
|
||||
}
|
||||
element = null;
|
||||
parents.clear();
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
}
|
||||
|
||||
public void validate(Object object) {
|
||||
if (element != null) {
|
||||
if (element.equals(object) || parents.contains(object)) {
|
||||
cancel();
|
||||
element = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setDeferredExpansion(Object toExpand) {
|
||||
element = toExpand;
|
||||
parents.clear();
|
||||
addAllParents(parents, element);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class SelectionJob extends UIJob {
|
||||
|
||||
private IStructuredSelection selection;
|
||||
private Object first;
|
||||
private final List<Object> parents = new ArrayList<Object>(); // top down
|
||||
|
||||
/**
|
||||
* Constucts a job to select the given element.
|
||||
*
|
||||
*/
|
||||
public SelectionJob() {
|
||||
super("Selection"); //$NON-NLS-1$
|
||||
setPriority(Job.INTERACTIVE);
|
||||
setSystem(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
@Override
|
||||
public IStatus runInUIThread(IProgressMonitor monitor) {
|
||||
if (getControl().isDisposed() || selection == null) {
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
synchronized (RemoteTreeViewer.this) {
|
||||
boolean allParentsExpanded = true;
|
||||
Iterator<Object> iterator = parents.iterator();
|
||||
while (iterator.hasNext() && !monitor.isCanceled()) {
|
||||
Object parent = iterator.next();
|
||||
Widget item = findItem(parent);
|
||||
if (item != null) {
|
||||
expandToLevel(parent, 1);
|
||||
} else {
|
||||
allParentsExpanded = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allParentsExpanded) {
|
||||
if (findItem(first) != null) {
|
||||
setSelection(selection, true);
|
||||
selection = null;
|
||||
first = null;
|
||||
parents.clear();
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
}
|
||||
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
}
|
||||
|
||||
public void setDeferredSelection(IStructuredSelection sel) {
|
||||
selection = sel;
|
||||
first = selection.getFirstElement();
|
||||
parents.clear();
|
||||
addAllParents(parents, first);
|
||||
}
|
||||
|
||||
public void validate(Object object) {
|
||||
if (first != null) {
|
||||
if (first.equals(object) || parents.contains(object)) {
|
||||
cancel();
|
||||
selection = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a remote tree viewer parented by the given composite.
|
||||
*
|
||||
* @param parent
|
||||
* parent composite
|
||||
*/
|
||||
public RemoteTreeViewer(Composite parent) {
|
||||
super(parent);
|
||||
addDisposeListener();
|
||||
fExpansionJob = new ExpansionJob();
|
||||
fSelectionJob = new SelectionJob();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a remote tree viewer parented by the given composite
|
||||
* with the given style.
|
||||
*
|
||||
* @param parent
|
||||
* parent composite
|
||||
* @param style
|
||||
* style bits
|
||||
*/
|
||||
public RemoteTreeViewer(Composite parent, int style) {
|
||||
super(parent, style);
|
||||
addDisposeListener();
|
||||
fExpansionJob = new ExpansionJob();
|
||||
fSelectionJob = new SelectionJob();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a remote tree viewer with the given tree.
|
||||
*
|
||||
* @param tree
|
||||
* tree widget
|
||||
*/
|
||||
public RemoteTreeViewer(Tree tree) {
|
||||
super(tree);
|
||||
addDisposeListener();
|
||||
fExpansionJob = new ExpansionJob();
|
||||
fSelectionJob = new SelectionJob();
|
||||
}
|
||||
|
||||
private void addDisposeListener() {
|
||||
getControl().addDisposeListener(new DisposeListener() {
|
||||
@Override
|
||||
public void widgetDisposed(DisposeEvent e) {
|
||||
cancelJobs();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void runDeferredUpdates() {
|
||||
if (fExpansionJob != null) {
|
||||
fExpansionJob.schedule();
|
||||
}
|
||||
if (fSelectionJob != null) {
|
||||
fSelectionJob.schedule();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The given element is being removed from the tree. Cancel
|
||||
* any deferred updates for the element.
|
||||
*
|
||||
* @param element
|
||||
*/
|
||||
protected void validateDeferredUpdates(Object element) {
|
||||
if (element != null) {
|
||||
if (fExpansionJob != null) {
|
||||
fExpansionJob.validate(element);
|
||||
}
|
||||
if (fSelectionJob != null) {
|
||||
fSelectionJob.validate(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.AbstractTreeViewer#add(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public synchronized void add(Object parentElement, Object childElement) {
|
||||
super.add(parentElement, childElement);
|
||||
runDeferredUpdates();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.AbstractTreeViewer#add(java.lang.Object, java.lang.Object[])
|
||||
*/
|
||||
@Override
|
||||
public synchronized void add(Object parentElement, Object[] childElements) {
|
||||
super.add(parentElement, childElements);
|
||||
runDeferredUpdates();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.AbstractTreeViewer#remove(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public synchronized void remove(Object element) {
|
||||
validateDeferredUpdates(element);
|
||||
super.remove(element);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.AbstractTreeViewer#remove(java.lang.Object[])
|
||||
*/
|
||||
@Override
|
||||
public synchronized void remove(Object[] elements) {
|
||||
for (Object element : elements) {
|
||||
validateDeferredUpdates(element);
|
||||
}
|
||||
super.remove(elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels any deferred updates currently scheduled/running.
|
||||
*/
|
||||
public void cancelJobs() {
|
||||
cancel(fSelectionJob);
|
||||
cancel(fExpansionJob);
|
||||
}
|
||||
|
||||
public synchronized void deferExpansion(Object element) {
|
||||
TreeItem treeItem = (TreeItem) findItem(element);
|
||||
if (treeItem == null) {
|
||||
fExpansionJob.setDeferredExpansion(element);
|
||||
fExpansionJob.schedule();
|
||||
} else {
|
||||
if (!getExpanded(treeItem)) {
|
||||
fExpansionJob.setDeferredExpansion(element);
|
||||
fExpansionJob.schedule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void deferSelection(IStructuredSelection selection) {
|
||||
if (fSelectionJob == null) {
|
||||
fSelectionJob = new SelectionJob();
|
||||
}
|
||||
|
||||
fSelectionJob.setDeferredSelection(selection);
|
||||
fSelectionJob.schedule();
|
||||
}
|
||||
|
||||
public IStructuredSelection getDeferredSelection() {
|
||||
if (fSelectionJob != null) {
|
||||
return fSelectionJob.selection;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void cancel(Job job) {
|
||||
if (job != null) {
|
||||
job.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void addAllParents(List<Object> list, Object element) {
|
||||
if (element instanceof IAdaptable) {
|
||||
IAdaptable adaptable = (IAdaptable) element;
|
||||
IWorkbenchAdapter adapter = (IWorkbenchAdapter) adaptable.getAdapter(IWorkbenchAdapter.class);
|
||||
if (adapter != null) {
|
||||
Object parent = adapter.getParent(element);
|
||||
if (parent != null) {
|
||||
list.add(0, parent);
|
||||
addAllParents(list, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] filter(Object[] elements) {
|
||||
return super.filter(elements);
|
||||
}
|
||||
|
||||
public Object[] getCurrentChildren(Object parent) {
|
||||
Widget widget = findItem(parent);
|
||||
if (widget != null) {
|
||||
Item[] items = getChildren(widget);
|
||||
Object[] children = new Object[items.length];
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
Object data = items[i].getData();
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
children[i] = data;
|
||||
}
|
||||
return children;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized void prune(final Object parent, final int offset) {
|
||||
Widget widget = findItem(parent);
|
||||
if (widget != null) {
|
||||
final Item[] currentChildren = getChildren(widget);
|
||||
if (offset < currentChildren.length) {
|
||||
preservingSelection(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = offset; i < currentChildren.length; i++) {
|
||||
if (currentChildren[i].getData() != null) {
|
||||
disassociate(currentChildren[i]);
|
||||
}
|
||||
currentChildren[i].dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void replace(final Object parent, final Object[] children, final int offset) {
|
||||
preservingSelection(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Widget widget = findItem(parent);
|
||||
if (widget == null) {
|
||||
add(parent, children);
|
||||
} else {
|
||||
Item[] currentChildren = getChildren(widget);
|
||||
int pos = offset;
|
||||
if (pos >= currentChildren.length) {
|
||||
// append
|
||||
add(parent, children);
|
||||
} else {
|
||||
// replace
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
Object child = children[i];
|
||||
if (pos < currentChildren.length) {
|
||||
// replace
|
||||
Item item = currentChildren[pos];
|
||||
Object data = item.getData();
|
||||
if (!child.equals(data)) {
|
||||
// no need to cancel pending updates here, the child may have shifted up/down
|
||||
internalRefresh(item, child, true, true);
|
||||
} else {
|
||||
// If it's the same child, the label/content may still have changed
|
||||
doUpdateItem(item, child);
|
||||
updatePlus(item, child);
|
||||
}
|
||||
} else {
|
||||
// add
|
||||
int numLeft = children.length - i;
|
||||
if (numLeft > 1) {
|
||||
Object[] others = new Object[numLeft];
|
||||
System.arraycopy(children, i, others, 0, numLeft);
|
||||
add(parent, others);
|
||||
} else {
|
||||
add(parent, child);
|
||||
}
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
runDeferredUpdates();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -53,6 +53,8 @@ public class Messages extends NLS {
|
|||
public static String LocalUIConnectionManager_2;
|
||||
public static String LocalUIConnectionManager_3;
|
||||
|
||||
public static String PendingUpdateAdapter_Pending;
|
||||
|
||||
public static String PTPRemoteUIPlugin_3;
|
||||
public static String PTPRemoteUIPlugin_4;
|
||||
|
||||
|
@ -91,6 +93,10 @@ public class Messages extends NLS {
|
|||
public static String RemoteResourceBrowser_NewFolder;
|
||||
public static String RemoteResourceBrowser_Show_hidden_files;
|
||||
public static String RemoteResourceBrowser_UpOneLevel;
|
||||
|
||||
public static String RemoteResourceBrowserWidget_New_Folder;
|
||||
|
||||
public static String RemoteResourceBrowserWidget_Unable_to_create_new_folder;
|
||||
|
||||
public static String RemoteUIServices_Configuring_remote_services;
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ LocalUIConnectionManager_0=Connection Error
|
|||
LocalUIConnectionManager_1=Could not open connection
|
||||
LocalUIConnectionManager_2=Can not create local connection
|
||||
LocalUIConnectionManager_3=It is not possible to create a connection for the local connection provider. Select a different remote provider first.
|
||||
PendingUpdateAdapter_Pending=Pending...
|
||||
PTPRemoteUIPlugin_3=Internal Error
|
||||
PTPRemoteUIPlugin_4=Initializing remote services
|
||||
RemoteConnectionWidget_Connection_Type=Connection Type
|
||||
|
@ -48,13 +49,15 @@ RemoteResourceBrowser_resourceTitle=Browse Resource
|
|||
RemoteResourceBrowser_fileTitle=Browse File
|
||||
RemoteResourceBrowser_directoryTitle=Browse Directory
|
||||
RemoteResourceBrowser_resourceLabel=Select resource:
|
||||
RemoteResourceBrowser_fileLabel=Select file:
|
||||
RemoteResourceBrowser_directoryLabel=Select directory:
|
||||
RemoteResourceBrowser_fileLabel=Selected file:
|
||||
RemoteResourceBrowser_directoryLabel=Selected directory:
|
||||
RemoteResourceBrowser_connectonLabel=Connection:
|
||||
RemoteResourceBrowser_newConnection=New...
|
||||
RemoteResourceBrowser_NewFolder=New folder
|
||||
RemoteResourceBrowser_Show_hidden_files=Show hidden files
|
||||
RemoteResourceBrowser_UpOneLevel=Up one level
|
||||
RemoteResourceBrowserWidget_New_Folder=New Folder
|
||||
RemoteResourceBrowserWidget_Unable_to_create_new_folder=Unable to create new folder
|
||||
RemoteUIServices_Configuring_remote_services=Configuring remote services...
|
||||
RemoteUIServicesProxy_1=Missing {0} attribute
|
||||
RemoteUIServicesProxy_2=Failed to instantiate factory: {0} in type: {1} in plugin: {2}
|
||||
|
|
|
@ -10,51 +10,23 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.remote.ui.dialogs;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import org.eclipse.core.filesystem.IFileStore;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.jface.dialogs.Dialog;
|
||||
import org.eclipse.jface.dialogs.IDialogConstants;
|
||||
import org.eclipse.jface.viewers.DoubleClickEvent;
|
||||
import org.eclipse.jface.viewers.IDoubleClickListener;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.jface.viewers.SelectionChangedEvent;
|
||||
import org.eclipse.jface.viewers.TreeViewer;
|
||||
import org.eclipse.jface.viewers.Viewer;
|
||||
import org.eclipse.jface.viewers.ViewerFilter;
|
||||
import org.eclipse.remote.core.IRemoteConnection;
|
||||
import org.eclipse.remote.core.IRemoteFileManager;
|
||||
import org.eclipse.remote.core.IRemoteServices;
|
||||
import org.eclipse.remote.internal.ui.DeferredFileStore;
|
||||
import org.eclipse.remote.internal.ui.RemoteContentProvider;
|
||||
import org.eclipse.remote.internal.ui.RemoteResourceComparator;
|
||||
import org.eclipse.remote.internal.ui.RemoteUIImages;
|
||||
import org.eclipse.remote.internal.ui.messages.Messages;
|
||||
import org.eclipse.remote.ui.IRemoteUIConnectionManager;
|
||||
import org.eclipse.remote.ui.RemoteUIServices;
|
||||
import org.eclipse.remote.ui.widgets.RemoteConnectionWidget;
|
||||
import org.eclipse.remote.ui.widgets.RemoteResourceBrowserWidget;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.FocusEvent;
|
||||
import org.eclipse.swt.events.FocusListener;
|
||||
import org.eclipse.swt.events.ModifyEvent;
|
||||
import org.eclipse.swt.events.ModifyListener;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
import org.eclipse.swt.widgets.Tree;
|
||||
import org.eclipse.ui.model.WorkbenchLabelProvider;
|
||||
import org.eclipse.ui.progress.PendingUpdateAdapter;
|
||||
|
||||
/**
|
||||
* Generic file/directory browser for remote resources.
|
||||
|
@ -70,29 +42,16 @@ public class RemoteResourceBrowser extends Dialog {
|
|||
public static final int MULTI = 0x02;
|
||||
|
||||
private final static int widthHint = 300;
|
||||
private final static int heightHint = 300;
|
||||
|
||||
private Tree tree = null;
|
||||
private TreeViewer treeViewer;
|
||||
private Text remotePathText;
|
||||
private Button okButton;
|
||||
private Button upButton;
|
||||
private Button newFolderButton;
|
||||
private RemoteConnectionWidget fRemoteConnectionWidget;
|
||||
private RemoteResourceBrowserWidget fWidget;
|
||||
|
||||
private int browserType;
|
||||
private String dialogTitle;
|
||||
private String dialogLabel;
|
||||
|
||||
private boolean showConnections = false;
|
||||
private boolean showHidden = false;
|
||||
private String remotePath = EMPTY_STRING;
|
||||
private String remotePaths[];
|
||||
private String fInitialPath;
|
||||
private IPath fRootPath;
|
||||
private IRemoteFileManager fFileMgr;
|
||||
private IRemoteConnection fConnection;
|
||||
private final IRemoteUIConnectionManager fUIConnMgr;
|
||||
private final IRemoteConnection fConnection;
|
||||
private int optionFlags = SINGLE;
|
||||
|
||||
public RemoteResourceBrowser(IRemoteServices services, IRemoteConnection conn, Shell parent, int flags) {
|
||||
|
@ -103,64 +62,8 @@ public class RemoteResourceBrowser extends Dialog {
|
|||
if (conn == null) {
|
||||
showConnections = true;
|
||||
}
|
||||
fUIConnMgr = RemoteUIServices.getRemoteUIServices(services).getUIConnectionManager();
|
||||
setTitle(Messages.RemoteResourceBrowser_resourceTitle);
|
||||
setType(FILE_BROWSER | DIRECTORY_BROWSER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the viewers input. Called when a new connection is selected.
|
||||
*
|
||||
* @param conn
|
||||
* new connection
|
||||
* @return true if input successfully changed
|
||||
*/
|
||||
private boolean changeInput(final IRemoteConnection conn) {
|
||||
if (conn == null) {
|
||||
return false;
|
||||
}
|
||||
if (fUIConnMgr != null) {
|
||||
fUIConnMgr.openConnectionWithProgress(getShell(), null, conn);
|
||||
}
|
||||
if (!conn.isOpen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fFileMgr = conn.getFileManager();
|
||||
if (fFileMgr != null) {
|
||||
/*
|
||||
* Note: the call to findInitialPath must happen before the
|
||||
* treeViewer input is set or the treeViewer fails. No idea why this
|
||||
* is.
|
||||
*/
|
||||
String cwd = conn.getWorkingDirectory();
|
||||
IPath initial = findInitialPath(cwd, fInitialPath);
|
||||
|
||||
// TODO: not platform independent - needs IRemotePath
|
||||
setRoot(initial.toString());
|
||||
|
||||
fConnection = conn;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* When a new connection is selected, make sure it is open before using it.
|
||||
*/
|
||||
private void connectionSelected() {
|
||||
/*
|
||||
* Make sure the connection is open before we try and read from the
|
||||
* connection.
|
||||
*/
|
||||
final IRemoteConnection conn = fRemoteConnectionWidget.getConnection();
|
||||
if (!changeInput(conn)) {
|
||||
/*
|
||||
* Reset combo back to the previous selection
|
||||
*/
|
||||
fRemoteConnectionWidget.setConnection(fConnection);
|
||||
}
|
||||
setType(FILE_BROWSER);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -190,10 +93,13 @@ public class RemoteResourceBrowser extends Dialog {
|
|||
protected Control createContents(Composite parent) {
|
||||
Control contents = super.createContents(parent);
|
||||
setTitle(dialogTitle);
|
||||
remotePathText.setText(remotePath);
|
||||
if (!showConnections) {
|
||||
changeInput(fConnection);
|
||||
fWidget.setConnection(fConnection);
|
||||
}
|
||||
if (fInitialPath != null) {
|
||||
fWidget.setInitialPath(fInitialPath);
|
||||
}
|
||||
updateDialog();
|
||||
return contents;
|
||||
}
|
||||
|
||||
|
@ -207,188 +113,56 @@ public class RemoteResourceBrowser extends Dialog {
|
|||
@Override
|
||||
protected Control createDialogArea(Composite parent) {
|
||||
Composite main = (Composite) super.createDialogArea(parent);
|
||||
GridData gd = new GridData(SWT.FILL, SWT.TOP, true, true);
|
||||
gd.widthHint = widthHint;
|
||||
main.setLayoutData(gd);
|
||||
main.setLayout(new GridLayout(1, true));
|
||||
|
||||
final Composite dialogComp = new Composite(main, SWT.NONE);
|
||||
dialogComp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
|
||||
GridLayout layout = new GridLayout();
|
||||
layout.numColumns = 4;
|
||||
dialogComp.setLayout(layout);
|
||||
|
||||
int options = RemoteResourceBrowserWidget.SHOW_HIDDEN_CHECKBOX | RemoteResourceBrowserWidget.SHOW_NEW_FOLDER_BUTTON;
|
||||
int style = SWT.NONE;
|
||||
if (showConnections) {
|
||||
fRemoteConnectionWidget = new RemoteConnectionWidget(dialogComp, SWT.NONE, null,
|
||||
RemoteConnectionWidget.FLAG_NO_LOCAL_SELECTION, null);
|
||||
fRemoteConnectionWidget.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 4, 1));
|
||||
fRemoteConnectionWidget.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
connectionSelected();
|
||||
updateDialog();
|
||||
}
|
||||
});
|
||||
options |= RemoteResourceBrowserWidget.SHOW_CONNECTIONS;
|
||||
}
|
||||
if (browserType == DIRECTORY_BROWSER) {
|
||||
options |= RemoteResourceBrowserWidget.DIRECTORY_BROWSER;
|
||||
}
|
||||
if ((optionFlags & MULTI) == MULTI) {
|
||||
style = SWT.MULTI;
|
||||
}
|
||||
|
||||
Label label = new Label(dialogComp, SWT.NONE);
|
||||
label.setText(dialogLabel);
|
||||
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
|
||||
gd.horizontalSpan = 1;
|
||||
label.setLayoutData(gd);
|
||||
|
||||
remotePathText = new Text(dialogComp, SWT.BORDER | SWT.SINGLE);
|
||||
remotePathText.addModifyListener(new ModifyListener() {
|
||||
fWidget = new RemoteResourceBrowserWidget(main, style, options);
|
||||
fWidget.addModifyListener(new ModifyListener() {
|
||||
@Override
|
||||
public void modifyText(ModifyEvent e) {
|
||||
remotePath = remotePathText.getText();
|
||||
updateDialog();
|
||||
}
|
||||
});
|
||||
remotePathText.addFocusListener(new FocusListener() {
|
||||
fWidget.addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
getShell().setDefaultButton(null); // allow text widget to receive SWT.DefaultSelection event
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
getShell().setDefaultButton(okButton);
|
||||
}
|
||||
});
|
||||
remotePathText.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
remotePathText.setSelection(remotePathText.getText().length());
|
||||
setRoot(remotePathText.getText());
|
||||
}
|
||||
|
||||
});
|
||||
gd = new GridData(GridData.FILL_HORIZONTAL);
|
||||
gd.widthHint = widthHint;
|
||||
remotePathText.setLayoutData(gd);
|
||||
|
||||
upButton = new Button(dialogComp, SWT.PUSH | SWT.FLAT);
|
||||
upButton.setImage(RemoteUIImages.get(RemoteUIImages.IMG_ELCL_UP_NAV));
|
||||
upButton.setToolTipText(Messages.RemoteResourceBrowser_UpOneLevel);
|
||||
upButton.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
if (!fRootPath.isRoot()) {
|
||||
setRoot(fRootPath.removeLastSegments(1).toOSString());
|
||||
}
|
||||
}
|
||||
});
|
||||
// new folder: See Bug 396334
|
||||
newFolderButton = new Button(dialogComp, SWT.PUSH | SWT.FLAT);
|
||||
newFolderButton.setImage(RemoteUIImages.get(RemoteUIImages.IMG_ELCL_NEW_FOLDER));
|
||||
newFolderButton.setToolTipText(Messages.RemoteResourceBrowser_NewFolder);
|
||||
newFolderButton.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
String pathText = remotePathText.getText();
|
||||
String newname = "/newfolder"; //$NON-NLS-1$
|
||||
remotePathText.setText(pathText + newname);
|
||||
remotePathText.setSelection(pathText.length() + 1, pathText.length() + newname.length());
|
||||
remotePathText.setFocus();
|
||||
}
|
||||
});
|
||||
|
||||
if ((optionFlags & MULTI) == MULTI) {
|
||||
tree = new Tree(main, SWT.MULTI | SWT.BORDER);
|
||||
} else {
|
||||
tree = new Tree(main, SWT.SINGLE | SWT.BORDER);
|
||||
}
|
||||
|
||||
gd = new GridData(GridData.FILL_BOTH);
|
||||
gd.horizontalSpan = 4;
|
||||
// see bug 158380
|
||||
gd.heightHint = Math.max(main.getParent().getSize().y, heightHint);
|
||||
tree.setLayoutData(gd);
|
||||
|
||||
treeViewer = new TreeViewer(tree);
|
||||
treeViewer.setContentProvider(new RemoteContentProvider());
|
||||
treeViewer.setLabelProvider(new WorkbenchLabelProvider());
|
||||
treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
|
||||
public void selectionChanged(SelectionChangedEvent event) {
|
||||
ISelection selection = event.getSelection();
|
||||
if (!selection.isEmpty() && selection instanceof IStructuredSelection) {
|
||||
IStructuredSelection ss = (IStructuredSelection) selection;
|
||||
Object element = ss.getFirstElement();
|
||||
if (element instanceof DeferredFileStore) {
|
||||
DeferredFileStore dfs = (DeferredFileStore) element;
|
||||
remotePathText.setText(dfs.getFileStore().toURI().getPath());
|
||||
}
|
||||
Vector<String> selectedPaths = new Vector<String>(ss.size());
|
||||
for (Object currentSelection : ss.toArray()) {
|
||||
if (currentSelection instanceof DeferredFileStore) {
|
||||
selectedPaths.add(((DeferredFileStore) currentSelection).getFileStore().toURI().getPath());
|
||||
}
|
||||
}
|
||||
remotePaths = selectedPaths.toArray(new String[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
treeViewer.setComparator(new RemoteResourceComparator());
|
||||
treeViewer.addDoubleClickListener(new IDoubleClickListener() {
|
||||
public void doubleClick(DoubleClickEvent event) {
|
||||
IStructuredSelection s = (IStructuredSelection) event.getSelection();
|
||||
Object o = s.getFirstElement();
|
||||
if (treeViewer.isExpandable(o)) {
|
||||
treeViewer.setExpandedState(o, !treeViewer.getExpandedState(o));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
if (browserType == DIRECTORY_BROWSER) {
|
||||
treeViewer.addFilter(new ViewerFilter() {
|
||||
@Override
|
||||
public boolean select(Viewer viewer, Object parentElement, Object element) {
|
||||
if ((element instanceof DeferredFileStore)) {
|
||||
return ((DeferredFileStore) element).isContainer();
|
||||
}
|
||||
return element instanceof PendingUpdateAdapter;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final Button showHiddenButton = new Button(main, SWT.CHECK);
|
||||
showHiddenButton.setText(Messages.RemoteResourceBrowser_Show_hidden_files);
|
||||
showHiddenButton.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
showHidden = showHiddenButton.getSelection();
|
||||
setRoot(fRootPath.toString());
|
||||
}
|
||||
});
|
||||
|
||||
updateDialog();
|
||||
fWidget.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true));
|
||||
|
||||
return main;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the initial path for the browser. If the initial path is not
|
||||
* supplied or does not exist on the remote machine, then the initial path
|
||||
* will be the cwd.
|
||||
*
|
||||
* @param cwd
|
||||
* @param initialPath
|
||||
* @return initial path
|
||||
*/
|
||||
private IPath findInitialPath(String cwd, String initialPath) {
|
||||
if (initialPath != null) {
|
||||
IPath path = new Path(initialPath);
|
||||
if (!path.isAbsolute()) {
|
||||
path = new Path(cwd).append(path);
|
||||
}
|
||||
if (fFileMgr.getResource(path.toString()).fetchInfo().exists()) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
return new Path(cwd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connection that was selected
|
||||
*
|
||||
* @return selected connection
|
||||
*/
|
||||
public IRemoteConnection getConnection() {
|
||||
return fConnection;
|
||||
if (fWidget != null) {
|
||||
return fWidget.getConnection();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -397,10 +171,10 @@ public class RemoteResourceBrowser extends Dialog {
|
|||
* @return selected path
|
||||
*/
|
||||
public String getPath() {
|
||||
if (remotePath.equals("")) { //$NON-NLS-1$
|
||||
return null;
|
||||
if (fWidget != null && fWidget.getPaths().size() > 0) {
|
||||
return fWidget.getPaths().get(0);
|
||||
}
|
||||
return remotePath;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -409,7 +183,10 @@ public class RemoteResourceBrowser extends Dialog {
|
|||
* @return selected paths
|
||||
*/
|
||||
public String[] getPaths() {
|
||||
return remotePaths;
|
||||
if (fWidget != null) {
|
||||
return fWidget.getPaths().toArray(new String[0]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -423,23 +200,6 @@ public class RemoteResourceBrowser extends Dialog {
|
|||
fInitialPath = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the root directory for the browser. This will also update the text
|
||||
* field with the path.
|
||||
*
|
||||
* @param path
|
||||
* path of root directory
|
||||
*/
|
||||
private void setRoot(String path) {
|
||||
if (fFileMgr != null) {
|
||||
IFileStore root = fFileMgr.getResource(path);
|
||||
treeViewer.setInput(new DeferredFileStore(root, !showHidden));
|
||||
remotePathText.setText(path);
|
||||
remotePathText.setSelection(remotePathText.getText().length());
|
||||
fRootPath = new Path(path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dialogTitle of the dialog.
|
||||
*
|
||||
|
@ -463,15 +223,10 @@ public class RemoteResourceBrowser extends Dialog {
|
|||
*/
|
||||
public void setType(int type) {
|
||||
browserType = type;
|
||||
if (type == FILE_BROWSER) {
|
||||
dialogLabel = Messages.RemoteResourceBrowser_fileLabel;
|
||||
setTitle(Messages.RemoteResourceBrowser_fileTitle);
|
||||
} else if (type == DIRECTORY_BROWSER) {
|
||||
dialogLabel = Messages.RemoteResourceBrowser_directoryLabel;
|
||||
if (type == DIRECTORY_BROWSER) {
|
||||
setTitle(Messages.RemoteResourceBrowser_directoryTitle);
|
||||
} else {
|
||||
dialogLabel = Messages.RemoteResourceBrowser_resourceLabel;
|
||||
setTitle(Messages.RemoteResourceBrowser_resourceTitle);
|
||||
setTitle(Messages.RemoteResourceBrowser_fileTitle);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -485,24 +240,9 @@ public class RemoteResourceBrowser extends Dialog {
|
|||
}
|
||||
|
||||
private void updateDialog() {
|
||||
if (okButton != null && upButton != null && newFolderButton != null) {
|
||||
okButton.setEnabled(false);
|
||||
upButton.setEnabled(false);
|
||||
newFolderButton.setEnabled(false);
|
||||
|
||||
if (fConnection != null) {
|
||||
if (remotePathText != null) {
|
||||
String pathText = remotePathText.getText();
|
||||
if (!pathText.equals(EMPTY_STRING)) {
|
||||
okButton.setEnabled(true);
|
||||
newFolderButton.setEnabled(true);
|
||||
IPath path = new Path(pathText);
|
||||
if (!path.isRoot()) {
|
||||
upButton.setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (okButton != null) {
|
||||
String path = getPath();
|
||||
okButton.setEnabled(getConnection() != null && path != null && !path.equals(EMPTY_STRING));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,10 @@ import org.eclipse.swt.widgets.Text;
|
|||
* button that uses the currently specified connection and a "Restore Default"
|
||||
* button to revert to the initial setting.
|
||||
*
|
||||
* If title is supplied then the widget will be placed in a group.
|
||||
* If GROUP_FLAG is set, then the widget will be placed in a group.
|
||||
* If RESTORE_BUTTON_FLAG is set, then a "Restore Default" button will be added
|
||||
*
|
||||
* If defaultPath is not null, then the initial path will be set to its value.
|
||||
*
|
||||
* The browse message can be modified using {@link #setBrowseMessage(String)}
|
||||
*
|
||||
|
@ -76,10 +79,6 @@ public class RemoteFileWidget extends Composite {
|
|||
body = group;
|
||||
}
|
||||
|
||||
// Composite textComp = new Composite(body, SWT.NONE);
|
||||
// textComp.setLayout(new GridLayout(2, false));
|
||||
// textComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
||||
|
||||
fLabel = new Label(body, SWT.NONE);
|
||||
fLabel.setText(Messages.RemoteFileWidget_File);
|
||||
fLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
|
||||
|
@ -87,6 +86,7 @@ public class RemoteFileWidget extends Composite {
|
|||
fText = new Text(body, SWT.BORDER);
|
||||
fText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
|
||||
fText.addModifyListener(new ModifyListener() {
|
||||
@Override
|
||||
public void modifyText(ModifyEvent e) {
|
||||
String path = fText.getText();
|
||||
setSavedPath(path);
|
||||
|
@ -94,12 +94,6 @@ public class RemoteFileWidget extends Composite {
|
|||
}
|
||||
});
|
||||
|
||||
// Composite buttonComp = new Composite(body, SWT.NONE);
|
||||
// buttonComp.setLayout(new GridLayout(2, true));
|
||||
// GridData buttonCompData = new GridData(SWT.FILL, SWT.FILL, false, false);
|
||||
// buttonCompData.horizontalAlignment = SWT.END;
|
||||
// buttonComp.setLayoutData(buttonCompData);
|
||||
|
||||
fBrowseButton = new Button(body, SWT.NONE);
|
||||
fBrowseButton.setText(Messages.RemoteFileWidget_Browse);
|
||||
GridData browseButtonData = new GridData(SWT.LEFT, SWT.CENTER, false, false);
|
||||
|
|
|
@ -0,0 +1,577 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008,2013 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 - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.remote.ui.widgets;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.filesystem.EFS;
|
||||
import org.eclipse.core.filesystem.IFileStore;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.ListenerList;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.SubMonitor;
|
||||
import org.eclipse.jface.dialogs.ErrorDialog;
|
||||
import org.eclipse.jface.operation.IRunnableWithProgress;
|
||||
import org.eclipse.jface.viewers.DoubleClickEvent;
|
||||
import org.eclipse.jface.viewers.IDoubleClickListener;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.jface.viewers.SelectionChangedEvent;
|
||||
import org.eclipse.jface.viewers.StructuredSelection;
|
||||
import org.eclipse.jface.viewers.TreePath;
|
||||
import org.eclipse.jface.viewers.TreeSelection;
|
||||
import org.eclipse.jface.viewers.Viewer;
|
||||
import org.eclipse.jface.viewers.ViewerFilter;
|
||||
import org.eclipse.remote.core.IRemoteConnection;
|
||||
import org.eclipse.remote.core.IRemoteFileManager;
|
||||
import org.eclipse.remote.internal.ui.DeferredFileStore;
|
||||
import org.eclipse.remote.internal.ui.DeferredFileStoreComparer;
|
||||
import org.eclipse.remote.internal.ui.PendingUpdateAdapter;
|
||||
import org.eclipse.remote.internal.ui.RemoteContentProvider;
|
||||
import org.eclipse.remote.internal.ui.RemoteResourceComparator;
|
||||
import org.eclipse.remote.internal.ui.RemoteTreeViewer;
|
||||
import org.eclipse.remote.internal.ui.RemoteUIImages;
|
||||
import org.eclipse.remote.internal.ui.messages.Messages;
|
||||
import org.eclipse.remote.ui.IRemoteUIConnectionManager;
|
||||
import org.eclipse.remote.ui.RemoteUIServices;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.ModifyEvent;
|
||||
import org.eclipse.swt.events.ModifyListener;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.eclipse.ui.model.WorkbenchLabelProvider;
|
||||
|
||||
/**
|
||||
* Generic file/directory browser for remote resources.
|
||||
*
|
||||
* @author greg
|
||||
*
|
||||
*/
|
||||
public class RemoteResourceBrowserWidget extends Composite {
|
||||
/**
|
||||
* Browse for files
|
||||
*/
|
||||
public static final int FILE_BROWSER = 0x01;
|
||||
/**
|
||||
* Browse for directories (files are not shown)
|
||||
*/
|
||||
public static final int DIRECTORY_BROWSER = 0x02;
|
||||
/**
|
||||
* Display checkbox to show/hide hidden files
|
||||
*/
|
||||
public static final int SHOW_HIDDEN_CHECKBOX = 0x10;
|
||||
/**
|
||||
* Display button to create new folders
|
||||
*/
|
||||
public static final int SHOW_NEW_FOLDER_BUTTON = 0x20;
|
||||
/**
|
||||
* Display widget to select a connection
|
||||
*/
|
||||
public static final int SHOW_CONNECTIONS = 0x40;
|
||||
|
||||
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
|
||||
|
||||
private static final int widthHint = 300;
|
||||
private static final int heightHint = 300;
|
||||
|
||||
private RemoteTreeViewer treeViewer;
|
||||
private Text remotePathText;
|
||||
private Button upButton;
|
||||
private Button newFolderButton;
|
||||
private RemoteConnectionWidget fRemoteConnectionWidget;
|
||||
|
||||
private String dialogTitle;
|
||||
private String dialogLabel;
|
||||
|
||||
private boolean showHidden;
|
||||
private final List<String> remotePaths = new ArrayList<String>();
|
||||
private String fInitialPath;
|
||||
private IPath fRootPath;
|
||||
private IRemoteFileManager fFileMgr;
|
||||
private IRemoteConnection fConnection;
|
||||
|
||||
private final ListenerList fModifyListeners = new ListenerList();
|
||||
|
||||
private int optionFlags = FILE_BROWSER | SHOW_HIDDEN_CHECKBOX | SHOW_NEW_FOLDER_BUTTON;
|
||||
|
||||
public RemoteResourceBrowserWidget(Composite parent, int style, int flags) {
|
||||
super(parent, style);
|
||||
setTitle(Messages.RemoteResourceBrowser_resourceTitle);
|
||||
|
||||
if (flags != 0) {
|
||||
optionFlags = flags;
|
||||
}
|
||||
|
||||
setType();
|
||||
|
||||
GridLayout layout = new GridLayout(1, false);
|
||||
layout.marginHeight = 0;
|
||||
layout.marginWidth = 0;
|
||||
setLayout(layout);
|
||||
|
||||
final Composite mainComp = new Composite(this, SWT.NONE);
|
||||
mainComp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
|
||||
layout = new GridLayout();
|
||||
layout.numColumns = 4;
|
||||
mainComp.setLayout(layout);
|
||||
|
||||
if ((optionFlags & SHOW_CONNECTIONS) != 0) {
|
||||
fRemoteConnectionWidget = new RemoteConnectionWidget(mainComp, SWT.NONE, null,
|
||||
RemoteConnectionWidget.FLAG_NO_LOCAL_SELECTION, null);
|
||||
fRemoteConnectionWidget.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 4, 1));
|
||||
fRemoteConnectionWidget.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
connectionSelected();
|
||||
updateEnablement();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Label label = new Label(mainComp, SWT.NONE);
|
||||
label.setText(dialogLabel);
|
||||
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
|
||||
gd.horizontalSpan = 1;
|
||||
label.setLayoutData(gd);
|
||||
|
||||
remotePathText = new Text(mainComp, SWT.BORDER | SWT.SINGLE);
|
||||
remotePathText.addModifyListener(new ModifyListener() {
|
||||
@Override
|
||||
public void modifyText(ModifyEvent e) {
|
||||
if (remotePaths.size() == 0) {
|
||||
remotePaths.add(remotePathText.getText());
|
||||
} else {
|
||||
remotePaths.set(0, remotePathText.getText());
|
||||
}
|
||||
notifyListeners(e);
|
||||
updateEnablement();
|
||||
}
|
||||
});
|
||||
remotePathText.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
remotePathText.setSelection(remotePathText.getText().length());
|
||||
setRoot(remotePathText.getText());
|
||||
}
|
||||
|
||||
});
|
||||
gd = new GridData(GridData.FILL_HORIZONTAL);
|
||||
gd.widthHint = widthHint;
|
||||
remotePathText.setLayoutData(gd);
|
||||
|
||||
upButton = new Button(mainComp, SWT.PUSH | SWT.FLAT);
|
||||
upButton.setImage(RemoteUIImages.get(RemoteUIImages.IMG_ELCL_UP_NAV));
|
||||
upButton.setToolTipText(Messages.RemoteResourceBrowser_UpOneLevel);
|
||||
upButton.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
if (!fRootPath.isRoot()) {
|
||||
setRoot(fRootPath.removeLastSegments(1).toOSString());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if ((optionFlags & SHOW_NEW_FOLDER_BUTTON) != 0) {
|
||||
// new folder: See Bug 396334
|
||||
newFolderButton = new Button(mainComp, SWT.PUSH | SWT.FLAT);
|
||||
newFolderButton.setImage(RemoteUIImages.get(RemoteUIImages.IMG_ELCL_NEW_FOLDER));
|
||||
newFolderButton.setToolTipText(Messages.RemoteResourceBrowser_NewFolder);
|
||||
newFolderButton.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
ISelection selection = treeViewer.getSelection();
|
||||
if (!selection.isEmpty()) {
|
||||
if (selection instanceof TreeSelection) {
|
||||
TreePath[] treePaths = ((TreeSelection) selection).getPaths();
|
||||
/*
|
||||
* There should only be one path
|
||||
*/
|
||||
if (treePaths.length > 0) {
|
||||
TreePath treePath = treePaths[0];
|
||||
if (treePath.getLastSegment() instanceof DeferredFileStore) {
|
||||
DeferredFileStore element = ((DeferredFileStore) treePath.getLastSegment());
|
||||
String path = element.getFileStore().toURI().getPath();
|
||||
String newPath = createNewFolder(path);
|
||||
if (newPath != null) {
|
||||
treeViewer.expandToLevel(element, 1);
|
||||
treeViewer.refresh(element);
|
||||
Object[] children = element.getChildren(null);
|
||||
for (Object child : children) {
|
||||
if (child instanceof DeferredFileStore
|
||||
&& newPath.equals(((DeferredFileStore) child).getFileStore().getName())) {
|
||||
treeViewer.deferSelection(new StructuredSelection(child));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DeferredFileStore root = (DeferredFileStore) treeViewer.getInput();
|
||||
String path = root.getFileStore().toURI().getPath();
|
||||
String newPath = createNewFolder(path);
|
||||
if (newPath != null) {
|
||||
treeViewer.refresh();
|
||||
treeViewer.getTree().setFocus();
|
||||
Object[] children = root.getChildren(null);
|
||||
for (Object child : children) {
|
||||
if (child instanceof DeferredFileStore
|
||||
&& newPath.equals(((DeferredFileStore) child).getFileStore().getName())) {
|
||||
treeViewer.deferSelection(new StructuredSelection(child));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ((style & SWT.MULTI) == SWT.MULTI) {
|
||||
treeViewer = new RemoteTreeViewer(mainComp, SWT.MULTI | SWT.BORDER);
|
||||
} else {
|
||||
treeViewer = new RemoteTreeViewer(mainComp, SWT.SINGLE | SWT.BORDER);
|
||||
}
|
||||
gd = new GridData(GridData.FILL_BOTH);
|
||||
gd.horizontalSpan = 4;
|
||||
// see bug 158380
|
||||
gd.heightHint = Math.max(parent.getSize().y, heightHint);
|
||||
treeViewer.getTree().setLayoutData(gd);
|
||||
// treeViewer.setUseHashlookup(true);
|
||||
treeViewer.setComparer(new DeferredFileStoreComparer());
|
||||
treeViewer.setComparator(new RemoteResourceComparator());
|
||||
treeViewer.setContentProvider(new RemoteContentProvider());
|
||||
treeViewer.setLabelProvider(new WorkbenchLabelProvider());
|
||||
treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
|
||||
@Override
|
||||
public void selectionChanged(SelectionChangedEvent event) {
|
||||
ISelection selection = event.getSelection();
|
||||
if (!selection.isEmpty() && selection instanceof IStructuredSelection) {
|
||||
IStructuredSelection ss = (IStructuredSelection) selection;
|
||||
remotePaths.clear();
|
||||
for (Object currentSelection : ss.toArray()) {
|
||||
if (currentSelection instanceof DeferredFileStore) {
|
||||
String path = ((DeferredFileStore) currentSelection).getFileStore().toURI().getPath();
|
||||
remotePaths.add(path);
|
||||
}
|
||||
}
|
||||
if (remotePaths.size() > 0) {
|
||||
remotePathText.setText(remotePaths.get(0));
|
||||
}
|
||||
updateEnablement();
|
||||
}
|
||||
}
|
||||
});
|
||||
treeViewer.addDoubleClickListener(new IDoubleClickListener() {
|
||||
@Override
|
||||
public void doubleClick(DoubleClickEvent event) {
|
||||
IStructuredSelection s = (IStructuredSelection) event.getSelection();
|
||||
Object o = s.getFirstElement();
|
||||
if (treeViewer.isExpandable(o)) {
|
||||
treeViewer.setExpandedState(o, !treeViewer.getExpandedState(o));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
if ((optionFlags & DIRECTORY_BROWSER) != 0) {
|
||||
treeViewer.addFilter(new ViewerFilter() {
|
||||
@Override
|
||||
public boolean select(Viewer viewer, Object parentElement, Object element) {
|
||||
if ((element instanceof DeferredFileStore)) {
|
||||
return ((DeferredFileStore) element).isContainer();
|
||||
}
|
||||
return element instanceof PendingUpdateAdapter;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ((optionFlags & SHOW_HIDDEN_CHECKBOX) != 0) {
|
||||
final Button showHiddenButton = new Button(mainComp, SWT.CHECK);
|
||||
showHiddenButton.setText(Messages.RemoteResourceBrowser_Show_hidden_files);
|
||||
showHiddenButton.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
showHidden = showHiddenButton.getSelection();
|
||||
setRoot(fRootPath.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateEnablement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener that will be notified when the directory path is modified.
|
||||
*
|
||||
* @param listener
|
||||
* listener to add
|
||||
*/
|
||||
public void addModifyListener(ModifyListener listener) {
|
||||
fModifyListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the viewers input. Called when a new connection is selected.
|
||||
*
|
||||
* @param conn
|
||||
* new connection
|
||||
* @return true if input successfully changed
|
||||
*/
|
||||
private boolean changeInput(final IRemoteConnection conn) {
|
||||
if (conn == null) {
|
||||
return false;
|
||||
}
|
||||
IRemoteUIConnectionManager uiMgr = RemoteUIServices.getRemoteUIServices(conn.getRemoteServices()).getUIConnectionManager();
|
||||
if (uiMgr != null) {
|
||||
uiMgr.openConnectionWithProgress(getShell(), null, conn);
|
||||
}
|
||||
if (!conn.isOpen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fFileMgr = conn.getFileManager();
|
||||
if (fFileMgr != null) {
|
||||
/*
|
||||
* Note: the call to findInitialPath must happen before the
|
||||
* treeViewer input is set or the treeViewer fails. No idea why this
|
||||
* is.
|
||||
*/
|
||||
String cwd = conn.getWorkingDirectory();
|
||||
IPath initial = findInitialPath(cwd, fInitialPath);
|
||||
|
||||
// TODO: not platform independent - needs IRemotePath
|
||||
setRoot(initial.toString());
|
||||
|
||||
fConnection = conn;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setConnection(IRemoteConnection connection) {
|
||||
changeInput(connection);
|
||||
updateEnablement();
|
||||
}
|
||||
|
||||
/**
|
||||
* When a new connection is selected, make sure it is open before using it.
|
||||
*/
|
||||
private void connectionSelected() {
|
||||
/*
|
||||
* Make sure the connection is open before we try and read from the
|
||||
* connection.
|
||||
*/
|
||||
final IRemoteConnection conn = fRemoteConnectionWidget.getConnection();
|
||||
if (!changeInput(conn)) {
|
||||
/*
|
||||
* Reset combo back to the previous selection
|
||||
*/
|
||||
fRemoteConnectionWidget.setConnection(fConnection);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
private String createNewFolder(final String parent) {
|
||||
final String[] name = new String[1];
|
||||
name[0] = null;
|
||||
try {
|
||||
PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
|
||||
@Override
|
||||
public void run(IProgressMonitor monitor) {
|
||||
SubMonitor progress = SubMonitor.convert(monitor, 10);
|
||||
String baseName = "newfolder"; //$NON-NLS-1$
|
||||
IFileStore path = fConnection.getFileManager().getResource(parent);
|
||||
IFileStore child = path.getChild(baseName);
|
||||
int count = 1;
|
||||
try {
|
||||
while (!progress.isCanceled() && child.fetchInfo(EFS.NONE, progress.newChild(1)).exists()) {
|
||||
progress.setWorkRemaining(10);
|
||||
child = path.getChild(baseName + " (" + count++ + ")"); //$NON-NLS-1$//$NON-NLS-2$
|
||||
}
|
||||
if (!progress.isCanceled()) {
|
||||
child.mkdir(EFS.SHALLOW, progress.newChild(10));
|
||||
name[0] = child.getName();
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
ErrorDialog.openError(getShell(), Messages.RemoteResourceBrowserWidget_New_Folder,
|
||||
Messages.RemoteResourceBrowserWidget_Unable_to_create_new_folder, e.getStatus());
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (InvocationTargetException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return name[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the initial path for the browser. If the initial path is not
|
||||
* supplied or does not exist on the remote machine, then the initial path
|
||||
* will be the cwd.
|
||||
*
|
||||
* @param cwd
|
||||
* @param initialPath
|
||||
* @return initial path
|
||||
*/
|
||||
private IPath findInitialPath(String cwd, String initialPath) {
|
||||
if (initialPath != null) {
|
||||
IPath path = new Path(initialPath);
|
||||
if (!path.isAbsolute()) {
|
||||
path = new Path(cwd).append(path);
|
||||
}
|
||||
if (fFileMgr.getResource(path.toString()).fetchInfo().exists()) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
return new Path(cwd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connection that was selected
|
||||
*
|
||||
* @return selected connection
|
||||
*/
|
||||
public IRemoteConnection getConnection() {
|
||||
return fConnection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the paths that were selected.
|
||||
*
|
||||
* @return selected paths
|
||||
*/
|
||||
public List<String> getPaths() {
|
||||
return remotePaths;
|
||||
}
|
||||
|
||||
private void notifyListeners(ModifyEvent e) {
|
||||
for (Object listener : fModifyListeners.getListeners()) {
|
||||
((ModifyListener) listener).modifyText(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a listener that will be notified when the directory path is
|
||||
* modified.
|
||||
*
|
||||
* @param listener
|
||||
* listener to remove
|
||||
*/
|
||||
public void removeModifyListener(ModifyListener listener) {
|
||||
fModifyListeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the initial path to start browsing. This will be set in the browser
|
||||
* text field, and in a future version should expand the browser to this
|
||||
* location if it exists.
|
||||
*
|
||||
* @param path
|
||||
*/
|
||||
public void setInitialPath(String path) {
|
||||
fInitialPath = path;
|
||||
updateEnablement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the root directory for the browser. This will also update the text
|
||||
* field with the path.
|
||||
*
|
||||
* @param path
|
||||
* path of root directory
|
||||
*/
|
||||
private void setRoot(String path) {
|
||||
if (fFileMgr != null) {
|
||||
IFileStore root = fFileMgr.getResource(path);
|
||||
treeViewer.setInput(new DeferredFileStore(root, !showHidden));
|
||||
remotePathText.setText(path);
|
||||
remotePathText.setSelection(remotePathText.getText().length());
|
||||
fRootPath = new Path(path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dialogTitle of the dialog.
|
||||
*
|
||||
* @param title
|
||||
*/
|
||||
public void setTitle(String title) {
|
||||
dialogTitle = title;
|
||||
if (dialogTitle == null) {
|
||||
dialogTitle = ""; //$NON-NLS-1$
|
||||
}
|
||||
Shell shell = getShell();
|
||||
if ((shell != null) && !shell.isDisposed()) {
|
||||
shell.setText(dialogTitle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type of browser. Can be either a file browser (allows selection
|
||||
* of files) or a directory browser (allows selection of directories), or
|
||||
* both.
|
||||
*/
|
||||
public void setType() {
|
||||
if ((optionFlags & FILE_BROWSER) == FILE_BROWSER) {
|
||||
dialogLabel = Messages.RemoteResourceBrowser_fileLabel;
|
||||
setTitle(Messages.RemoteResourceBrowser_fileTitle);
|
||||
} else {
|
||||
dialogLabel = Messages.RemoteResourceBrowser_directoryLabel;
|
||||
setTitle(Messages.RemoteResourceBrowser_directoryTitle);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEnablement() {
|
||||
boolean upEnabled = false;
|
||||
boolean newFolderEnabled = false;
|
||||
|
||||
if (fConnection != null && fConnection.isOpen()) {
|
||||
if (remotePaths.size() == 1) {
|
||||
String pathText = remotePaths.get(0);
|
||||
if (!pathText.equals(EMPTY_STRING)) {
|
||||
if (fConnection.getFileManager().getResource(pathText).fetchInfo().isDirectory()) {
|
||||
newFolderEnabled = true;
|
||||
}
|
||||
IPath path = new Path(pathText);
|
||||
if (!path.isRoot()) {
|
||||
upEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (upButton != null) {
|
||||
upButton.setEnabled(upEnabled);
|
||||
}
|
||||
if (newFolderButton != null) {
|
||||
newFolderButton.setEnabled(newFolderEnabled);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue