diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/MakeContentProvider.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/MakeContentProvider.java index c4ba0e997cc..65d3e587fd2 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/MakeContentProvider.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/MakeContentProvider.java @@ -14,15 +14,19 @@ import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.core.MakeTargetEvent; import org.eclipse.core.resources.IContainer; 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.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.viewers.AbstractTreeViewer; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.widgets.Control; -public class MakeContentProvider implements ITreeContentProvider, IMakeTargetListener { - +public class MakeContentProvider implements ITreeContentProvider, IMakeTargetListener, IResourceChangeListener { protected boolean bFlatten; protected StructuredViewer viewer; @@ -99,7 +103,27 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis if (this.viewer == null) { MakeCorePlugin.getDefault().getTargetManager().addListener(this); } - this.viewer = (StructuredViewer)viewer; + this.viewer = (StructuredViewer) viewer; + IWorkspace oldWorkspace = null; + IWorkspace newWorkspace = null; + if (oldInput instanceof IWorkspace) { + oldWorkspace = (IWorkspace) oldInput; + } else if (oldInput instanceof IContainer) { + oldWorkspace = ((IContainer) oldInput).getWorkspace(); + } + if (newInput instanceof IWorkspace) { + newWorkspace = (IWorkspace) newInput; + } else if (newInput instanceof IContainer) { + newWorkspace = ((IContainer) newInput).getWorkspace(); + } + if (oldWorkspace != newWorkspace) { + if (oldWorkspace != null) { + oldWorkspace.removeResourceChangeListener(this); + } + if (newWorkspace != null) { + newWorkspace.addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE); + } + } } public void targetChanged(final MakeTargetEvent event) { @@ -136,4 +160,80 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis } } } -} \ No newline at end of file + + void processDelta(IResourceDelta delta) { + // Bail out if the widget was disposed. + Control ctrl = viewer.getControl(); + if (ctrl == null || ctrl.isDisposed() || delta == null) { + return; + } + + IResourceDelta[] affectedChildren = delta.getAffectedChildren(IResourceDelta.CHANGED); + + // Not interested in Content changes. + for (int i = 0; i < affectedChildren.length; i++) { + if ((affectedChildren[i].getFlags() & IResourceDelta.TYPE) != 0) { + return; + } + } + + // Handle changed children recursively. + for (int i = 0; i < affectedChildren.length; i++) { + processDelta(affectedChildren[i]); + } + + // Get the affected resource + IResource resource = delta.getResource(); + + // Handle removed children. Issue one update for all removals. + affectedChildren = delta.getAffectedChildren(IResourceDelta.REMOVED); + if (affectedChildren.length > 0) { + ArrayList affected = new ArrayList(affectedChildren.length); + for (int i = 0; i < affectedChildren.length; i++) { + if (affectedChildren[i].getResource().getType() == IResource.FOLDER) { + affected.add(affectedChildren[i].getResource()); + } + } + if (affected.size() != 0) { + if (viewer instanceof AbstractTreeViewer) { + ((AbstractTreeViewer) viewer).remove(affected.toArray()); + } else { + viewer.refresh(resource); + } + } + } + + // Handle added children. Issue one update for all insertions. + affectedChildren = delta.getAffectedChildren(IResourceDelta.ADDED); + if (affectedChildren.length > 0) { + ArrayList affected = new ArrayList(affectedChildren.length); + for (int i = 0; i < affectedChildren.length; i++) { + if (affectedChildren[i].getResource().getType() == IResource.FOLDER) { + affected.add(affectedChildren[i].getResource()); + } + } + if (affected.size() != 0) { + if (viewer instanceof AbstractTreeViewer) { + ((AbstractTreeViewer) viewer).add(resource, affected.toArray()); + } else { + viewer.refresh(resource); + } + } + } + } + + public void resourceChanged(IResourceChangeEvent event) { + final IResourceDelta delta = event.getDelta(); + Control ctrl = viewer.getControl(); + if (ctrl != null && !ctrl.isDisposed()) { + // Do a sync exec, not an async exec, since the resource delta + // must be traversed in this method. It is destroyed + // when this method returns. + ctrl.getDisplay().syncExec(new Runnable() { + public void run() { + processDelta(delta); + } + }); + } + } +}