blob: 14f6173c9ead7f504c79ac06693516171958dc7e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM - Initial API and implementation
*******************************************************************************/
package org.eclipse.core.tools.resources;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.tools.*;
import org.eclipse.jface.action.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.*;
/**
* Resource Spy view. This view shows detailed information about the currently
* selected resource in any other view in the platform. For
* details on the information being presented, see <code>ResourceContentProvider
* </code> documentation (link below).
*
* @see org.eclipse.core.tools.resources.ResourceContentProvider
*/
public class ResourceView extends SpyView {
/** JFace's tree component used to present resource details. */
protected AbstractTreeViewer viewer;
/**
* Our listener to selection changes. Every time a new resource is
* selected, this view gets updated.
*/
private ISelectionListener selectionListener;
/**
* Our listener to resource changes. Every time the current selected
* resource is changed, this view gets updated.
*/
private IResourceChangeListener resourceChangeListener;
/** The content provider for this view's TreeViewer. */
private ResourceContentProvider contentProvider;
/**
* Constructs a resource view object, registering a resource change listener.
*/
public ResourceView() {
addResourceChangeListener();
}
/**
* Creates the SWT controls for the resource view.
*
* @param parent the parent control
* @see IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
@Override
public void createPartControl(Composite parent) {
viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
contentProvider = new ResourceContentProvider();
viewer.setContentProvider(contentProvider);
addSelectionListener();
createActions();
}
/**
* Creates and publishes this view's actions.
*/
private void createActions() {
IActionBars actionBars = this.getViewSite().getActionBars();
final GlobalAction copyAction = new CopyStructuredSelectionAction(new TreeSelectionProviderDecorator(viewer));
copyAction.registerAsGlobalAction(actionBars);
final GlobalAction selectAllAction = new SelectAllAction(new TreeTextOperationTarget((Tree) viewer.getControl()));
selectAllAction.registerAsGlobalAction(actionBars);
actionBars.updateActionBars();
final MenuManager menuMgr = new MenuManager();
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(manager -> manager.add(copyAction));
Menu menu = menuMgr.createContextMenu(viewer.getControl());
viewer.getControl().setMenu(menu);
}
/**
* Process the given selection. If it is not an structured selection, the event
* is discarded. If the selection is a resource (or maps to a resource),
* updates the resource view. Otherwise, the resource view is cleaned out.
*
* @param sel the selection object to be processed
*/
protected void processSelection(ISelection sel) {
// if it is not a strucutured selection, ignore
if (!(sel instanceof IStructuredSelection))
return;
IResource resource = null;
IStructuredSelection structuredSel = (IStructuredSelection) sel;
if (!structuredSel.isEmpty()) {
Object item = ((IStructuredSelection) sel).getFirstElement();
if (item instanceof IResource)
resource = (IResource) item;
else if (item instanceof IAdaptable)
resource = ((IAdaptable) item).getAdapter(IResource.class);
}
// loads the selected resource
if (resource != null)
loadResource(resource);
}
/**
* Creates a selection listener that will call
* <code>processSelection(ISelection)</code> everytime a selection has
* changed in any place.
*
* @see #processSelection(ISelection)
*/
private void addSelectionListener() {
ISelectionService selectionService = getSite().getPage().getWorkbenchWindow().getSelectionService();
// creates a selection listener that ignores who generated the event
selectionListener = (part, sel) -> processSelection(sel);
selectionService.addSelectionListener(selectionListener);
// forces a call to processSelection() to recognize any existing selection
processSelection(selectionService.getSelection());
}
/**
* Creates a resource change listener so we can know if the currently selected
* resource has changed or a marker has been added to or removed from it.
*/
private void addResourceChangeListener() {
resourceChangeListener = new SelectedResourceChangeListener();
ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceChangeListener, IResourceChangeEvent.POST_CHANGE);
}
/**
* Loads a resource to be shown on this resource view (or cleans it, if
* resource == null). This method must be run in the SWT thread.
*
* @param resource the resource to be shown on this view
* @see ResourceContentProvider#inputChanged(Viewer, Object, Object)
*/
public void loadResource(IResource resource) {
if (viewer.getControl().isDisposed())
return;
// turn redraw off so the UI will reflect changes only after we are done
viewer.getControl().setRedraw(false);
// fires viewer update
viewer.setInput(resource);
// shows all nodes in the resource tree
viewer.expandAll();
// we are done, turn redraw on
viewer.getControl().setRedraw(true);
}
/**
* Removes all listeners added.
*
* @see org.eclipse.ui.IWorkbenchPart#dispose()
*/
@Override
public void dispose() {
super.dispose();
removeSelectionListener();
removeResourceChangeListener();
}
/**
* Removes the resource change listener added by this view.
*/
private void removeResourceChangeListener() {
if (resourceChangeListener == null)
return;
ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceChangeListener);
resourceChangeListener = null;
}
/**
* Removes the selection listener added by this view.
*/
private void removeSelectionListener() {
if (selectionListener == null)
return;
ISelectionService selectionService = getSite().getPage().getWorkbenchWindow().getSelectionService();
selectionService.removeSelectionListener(selectionListener);
selectionListener = null;
}
/**
* A resource change listener that is interested on changes in the resource
* being currently shown.
*/
private class SelectedResourceChangeListener implements IResourceChangeListener {
public SelectedResourceChangeListener() {
}
@Override
public void resourceChanged(IResourceChangeEvent event) {
final IResource currentResource = (IResource) viewer.getInput();
// if we don't have a resource currently loaded, ignore the event
if (event.getType() != IResourceChangeEvent.POST_CHANGE || currentResource == null)
return;
// looks for a delta for the currently loaded resource
IResourceDelta rootDelta = event.getDelta();
IResourceDelta resourceDelta = rootDelta.findMember(currentResource.getFullPath());
// if there is a delta, something has changed
if (resourceDelta != null) {
// so rebuild the resource view contents with the new state
Display.getDefault().asyncExec(() -> loadResource(currentResource));
}
}
}
}