/******************************************************************************* * Copyright (c) 2014, 2015 Red Hat Inc. * 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: * Mickael Istria (Red Hat Inc.) - initial API and implementation ******************************************************************************/ package org.eclipse.ui.internal.navigator.resources.nested; import java.util.LinkedHashSet; import java.util.Set; import org.eclipse.core.commands.Command; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.commands.ICommandService; import org.eclipse.ui.handlers.HandlerUtil; import org.eclipse.ui.internal.navigator.resources.plugin.WorkbenchNavigatorPlugin; import org.eclipse.ui.navigator.CommonViewer; public class NestedProjectsContentProvider implements ITreeContentProvider, IResourceChangeListener { public static final String EXTENSION_ID = "org.eclipse.ui.navigator.resources.nested.nestedProjectContentProvider"; //$NON-NLS-1$ private Command projectPresetionCommand; private CommonViewer viewer; public NestedProjectsContentProvider() { ICommandService commandService = PlatformUI.getWorkbench().getService(ICommandService.class); this.projectPresetionCommand = commandService.getCommand(ProjectPresentationHandler.COMMAND_ID); try { HandlerUtil.updateRadioState(this.projectPresetionCommand, Boolean.TRUE.toString()); } catch (ExecutionException ex) { WorkbenchNavigatorPlugin.log(ex.getMessage(), new Status(IStatus.ERROR, WorkbenchNavigatorPlugin.PLUGIN_ID, ex.getMessage(), ex)); } ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE); } @Override public void dispose() { try { HandlerUtil.updateRadioState(this.projectPresetionCommand, Boolean.FALSE.toString()); } catch (ExecutionException ex) { WorkbenchNavigatorPlugin.log(ex.getMessage(), new Status(IStatus.ERROR, WorkbenchNavigatorPlugin.PLUGIN_ID, ex.getMessage(), ex)); } ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); } @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { this.viewer = (CommonViewer)viewer; } @Override public Object[] getElements(Object inputElement) { return null; } @Override public IProject[] getChildren(Object parentElement) { if (! (parentElement instanceof IContainer)) { return null; } IContainer container = (IContainer)parentElement; return NestedProjectManager.getInstance().getDirectChildrenProjects(container); } @Override public IContainer getParent(Object element) { if (element instanceof IProject) { IProject project = (IProject)element; if (NestedProjectManager.getInstance().isShownAsNested(project)) { return NestedProjectManager.getInstance().getMostDirectOpenContainer(project); } } return null; } @Override public boolean hasChildren(Object element) { if (element instanceof IContainer) { return NestedProjectManager.getInstance().hasDirectChildrenProjects((IContainer) element); } return false; } @Override public void resourceChanged(IResourceChangeEvent event) { IResourceDelta delta = event.getDelta(); if (delta == null || event.getType() != IResourceChangeEvent.POST_CHANGE) { return; } final Set<IContainer> parentsToRefresh = new LinkedHashSet<>(); if (delta.getKind() == IResourceDelta.CHANGED && delta.getResource() instanceof IWorkspaceRoot) { for (IResourceDelta childDelta : event.getDelta().getAffectedChildren()) { IResource childResource = childDelta.getResource(); if (childResource instanceof IProject && (childDelta.getKind() == IResourceDelta.ADDED || childDelta.getKind() == IResourceDelta.REMOVED)) { IProject affectedProject = (IProject) childResource; IContainer parent = getParent(affectedProject); if (parent != null) { parentsToRefresh.add(parent); } else { // workspace root parentsToRefresh.clear(); parentsToRefresh.add(affectedProject.getParent()); break; } } } } if (!parentsToRefresh.isEmpty()) { PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { @Override public void run() { if (viewer.getTree() == null || viewer.getTree().isDisposed()) { return; } for (IContainer parent : parentsToRefresh) { NestedProjectsContentProvider.this.viewer.refresh(parent); } } }); } } }