/******************************************************************************* * Copyright (c) 2000, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM - 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(new IMenuListener() { @Override public void menuAboutToShow(IMenuManager 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 = new ISelectionListener() { @Override public void selectionChanged(IWorkbenchPart part, ISelection 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(new Runnable() { @Override public void run() { loadResource(currentResource); } }); } } } }