mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 367559: avoid recursive refreshes of Make Targets view
This commit is contained in:
parent
e3bdead668
commit
032d94ff51
1 changed files with 93 additions and 165 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2000, 2010 QNX Software Systems and others.
|
* Copyright (c) 2000, 2011 QNX Software Systems and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -22,7 +22,6 @@ import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.CCorePreferenceConstants;
|
import org.eclipse.cdt.core.CCorePreferenceConstants;
|
||||||
import org.eclipse.cdt.core.model.CoreModel;
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
|
import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
|
||||||
import org.eclipse.cdt.core.settings.model.CSourceEntry;
|
|
||||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||||
import org.eclipse.cdt.core.settings.model.ICDescriptionDelta;
|
import org.eclipse.cdt.core.settings.model.ICDescriptionDelta;
|
||||||
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
||||||
|
@ -35,7 +34,6 @@ import org.eclipse.cdt.make.core.IMakeTargetListener;
|
||||||
import org.eclipse.cdt.make.core.MakeCorePlugin;
|
import org.eclipse.cdt.make.core.MakeCorePlugin;
|
||||||
import org.eclipse.cdt.make.core.MakeTargetEvent;
|
import org.eclipse.cdt.make.core.MakeTargetEvent;
|
||||||
import org.eclipse.core.resources.IContainer;
|
import org.eclipse.core.resources.IContainer;
|
||||||
import org.eclipse.core.resources.IFolder;
|
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.resources.IResource;
|
import org.eclipse.core.resources.IResource;
|
||||||
import org.eclipse.core.resources.IResourceChangeEvent;
|
import org.eclipse.core.resources.IResourceChangeEvent;
|
||||||
|
@ -48,9 +46,8 @@ import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChang
|
||||||
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
|
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
|
||||||
import org.eclipse.core.runtime.preferences.InstanceScope;
|
import org.eclipse.core.runtime.preferences.InstanceScope;
|
||||||
import org.eclipse.jface.viewers.ITreeContentProvider;
|
import org.eclipse.jface.viewers.ITreeContentProvider;
|
||||||
import org.eclipse.jface.viewers.StructuredViewer;
|
import org.eclipse.jface.viewers.TreeViewer;
|
||||||
import org.eclipse.jface.viewers.Viewer;
|
import org.eclipse.jface.viewers.Viewer;
|
||||||
import org.eclipse.swt.widgets.Control;
|
|
||||||
import org.eclipse.swt.widgets.Display;
|
import org.eclipse.swt.widgets.Display;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,7 +63,7 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis
|
||||||
/** presentation of the content, i.e. for MakeView tree of for BuildTargetDialog table */
|
/** presentation of the content, i.e. for MakeView tree of for BuildTargetDialog table */
|
||||||
protected boolean bFlatten;
|
protected boolean bFlatten;
|
||||||
|
|
||||||
protected StructuredViewer viewer;
|
protected TreeViewer viewer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
|
@ -85,9 +82,6 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis
|
||||||
bFlatten = flat;
|
bFlatten = flat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] getChildren(Object obj) {
|
public Object[] getChildren(Object obj) {
|
||||||
if (obj instanceof IWorkspaceRoot) {
|
if (obj instanceof IWorkspaceRoot) {
|
||||||
|
@ -155,9 +149,6 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis
|
||||||
return new Object[0];
|
return new Object[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Object getParent(Object obj) {
|
public Object getParent(Object obj) {
|
||||||
if (obj instanceof IMakeTarget) {
|
if (obj instanceof IMakeTarget) {
|
||||||
|
@ -174,17 +165,11 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasChildren(Object obj) {
|
public boolean hasChildren(Object obj) {
|
||||||
return getChildren(obj).length > 0;
|
return getChildren(obj).length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] getElements(Object obj) {
|
public Object[] getElements(Object obj) {
|
||||||
if (bFlatten) {
|
if (bFlatten) {
|
||||||
|
@ -199,9 +184,6 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis
|
||||||
return getChildren(obj);
|
return getChildren(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
if (viewer != null) {
|
if (viewer != null) {
|
||||||
|
@ -209,15 +191,12 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
|
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
|
||||||
if (this.viewer == null) {
|
if (this.viewer == null) {
|
||||||
MakeCorePlugin.getDefault().getTargetManager().addListener(this);
|
MakeCorePlugin.getDefault().getTargetManager().addListener(this);
|
||||||
}
|
}
|
||||||
this.viewer = (StructuredViewer) viewer;
|
this.viewer = (TreeViewer) viewer;
|
||||||
IWorkspace oldWorkspace = null;
|
IWorkspace oldWorkspace = null;
|
||||||
IWorkspace newWorkspace = null;
|
IWorkspace newWorkspace = null;
|
||||||
if (oldInput instanceof IWorkspace) {
|
if (oldInput instanceof IWorkspace) {
|
||||||
|
@ -249,142 +228,96 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/**
|
||||||
* @see org.eclipse.cdt.make.core.IMakeTargetListener#targetChanged(org.eclipse.cdt.make.core.MakeTargetEvent)
|
* Refresh the project tree or the project subtree (in case of drill-down adapter) in the view.
|
||||||
*/
|
*/
|
||||||
@Override
|
private void refreshProjectTree(final IProject project) {
|
||||||
public void targetChanged(final MakeTargetEvent event) {
|
Display.getDefault().asyncExec(new Runnable() {
|
||||||
final Control ctrl = viewer.getControl();
|
|
||||||
if (ctrl != null && !ctrl.isDisposed()) {
|
|
||||||
switch (event.getType()) {
|
|
||||||
case MakeTargetEvent.PROJECT_ADDED :
|
|
||||||
case MakeTargetEvent.PROJECT_REMOVED :
|
|
||||||
ctrl.getDisplay().asyncExec(new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!ctrl.isDisposed()) {
|
if (viewer == null || viewer.getControl() == null || viewer.getControl().isDisposed())
|
||||||
viewer.refresh();
|
return;
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case MakeTargetEvent.TARGET_ADD :
|
|
||||||
case MakeTargetEvent.TARGET_CHANGED :
|
|
||||||
case MakeTargetEvent.TARGET_REMOVED :
|
|
||||||
ctrl.getDisplay().asyncExec(new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
if (viewer.getTree().getItemCount() <= 0) {
|
||||||
public void run() {
|
return;
|
||||||
if (!ctrl.isDisposed()) {
|
}
|
||||||
if (bFlatten) {
|
|
||||||
viewer.refresh();
|
Object firstItem = viewer.getTree().getItem(0).getData();
|
||||||
|
IContainer parentContainer = null;
|
||||||
|
|
||||||
|
boolean isDrilledDown = !(firstItem instanceof IProject);
|
||||||
|
if (!isDrilledDown) {
|
||||||
|
// view shows projects
|
||||||
|
viewer.refresh(project);
|
||||||
} else {
|
} else {
|
||||||
//We can't just call refresh on the container target that
|
// drill-down adapter in the game
|
||||||
//has been created since it may be that the container has
|
if (firstItem instanceof IResource) {
|
||||||
//been filtered out and the filters in the viewer don't know
|
parentContainer = ((IResource) firstItem).getParent();
|
||||||
//any better how to call out to the filter selection again.
|
} else if (firstItem instanceof TargetSourceContainer) {
|
||||||
//Instead we walk to the root project container and refresh it.
|
parentContainer = ((TargetSourceContainer) firstItem).getContainer().getParent();
|
||||||
Set<IContainer> containers = new HashSet<IContainer>();
|
} else if (firstItem instanceof IMakeTarget) {
|
||||||
IMakeTarget[] targets = event.getTargets();
|
parentContainer = ((IMakeTarget) firstItem).getContainer();
|
||||||
for (IMakeTarget target : targets) {
|
|
||||||
IContainer container = target.getContainer();
|
|
||||||
while(!(container instanceof IProject) && container.getParent()!=null) {
|
|
||||||
container = container.getParent();
|
|
||||||
}
|
|
||||||
containers.add(container);
|
|
||||||
}
|
|
||||||
for (IContainer container : containers) {
|
|
||||||
viewer.refresh(container);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processDelta(IResourceDelta delta) {
|
if (parentContainer != null && project.equals(parentContainer.getProject())) {
|
||||||
// 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
|
|
||||||
final IResource resource = delta.getResource();
|
|
||||||
|
|
||||||
// Handle removed children. Issue one update for all removals.
|
|
||||||
affectedChildren = delta.getAffectedChildren(IResourceDelta.REMOVED);
|
|
||||||
if (affectedChildren.length > 0) {
|
|
||||||
for (int i = 0; i < affectedChildren.length; i++) {
|
|
||||||
if (affectedChildren[i].getResource().getType() == IResource.FOLDER) {
|
|
||||||
Display.getDefault().asyncExec(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (viewer == null || viewer.getControl() == null || viewer.getControl().isDisposed())
|
|
||||||
return;
|
|
||||||
// refresh the whole view as deletion may cause parent nodes to get filtered out
|
|
||||||
viewer.refresh();
|
viewer.refresh();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle added children. Issue one update for all insertions.
|
|
||||||
affectedChildren = delta.getAffectedChildren(IResourceDelta.ADDED);
|
|
||||||
if (affectedChildren.length > 0) {
|
|
||||||
final ArrayList<IResource> affected = new ArrayList<IResource>(affectedChildren.length);
|
|
||||||
for (int i = 0; i < affectedChildren.length; i++) {
|
|
||||||
if (affectedChildren[i].getResource().getType() == IResource.FOLDER) {
|
|
||||||
affected.add(affectedChildren[i].getResource());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!affected.isEmpty()) {
|
|
||||||
Display.getDefault().asyncExec(new Runnable() {
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void targetChanged(MakeTargetEvent event) {
|
||||||
if (viewer == null || viewer.getControl() == null || viewer.getControl().isDisposed())
|
Set<IProject> affectedProjects = new HashSet<IProject>();
|
||||||
|
for (IMakeTarget target : event.getTargets()) {
|
||||||
|
IContainer container = target.getContainer();
|
||||||
|
affectedProjects.add(container.getProject());
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the view is being filtered, adding/removing targets can
|
||||||
|
// result in showing or hiding containers or the project itself
|
||||||
|
for (IProject project : affectedProjects) {
|
||||||
|
refreshProjectTree(project);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void collectAffectedProjects(IResourceDelta delta, Set<IProject> affectedProjects) {
|
||||||
|
if (affectedProjects.contains(delta.getResource().getProject())) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (resource instanceof IFolder && CCorePlugin.showSourceRootsAtTopOfProject()) {
|
for (IResourceDelta d : delta.getAffectedChildren(IResourceDelta.ADDED | IResourceDelta.REMOVED)) {
|
||||||
// that will refresh equal TargetSourceContainer from the tree
|
IResource rc = d.getResource();
|
||||||
viewer.refresh(new TargetSourceContainer(new CSourceEntry((IFolder) resource, null, 0)));
|
int rcType = rc.getType();
|
||||||
}
|
if (rcType == IResource.PROJECT || rcType == IResource.FOLDER) {
|
||||||
viewer.refresh(resource);
|
affectedProjects.add(rc.getProject());
|
||||||
}
|
return;
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (IResourceDelta d : delta.getAffectedChildren(IResourceDelta.CHANGED)) {
|
||||||
|
collectAffectedProjects(d, affectedProjects);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void resourceChanged(IResourceChangeEvent event) {
|
public void resourceChanged(IResourceChangeEvent event) {
|
||||||
final IResourceDelta delta = event.getDelta();
|
IResourceDelta delta = event.getDelta();
|
||||||
Control ctrl = viewer.getControl();
|
if (delta == null) {
|
||||||
if (ctrl != null && !ctrl.isDisposed())
|
return;
|
||||||
processDelta(delta);
|
}
|
||||||
|
|
||||||
|
Set<IProject> affectedProjects = new HashSet<IProject>();
|
||||||
|
collectAffectedProjects(delta, affectedProjects);
|
||||||
|
|
||||||
|
// If the view is being filtered or source roots shown,
|
||||||
|
// adding/removing resources can structurally affect the tree
|
||||||
|
// starting with the project
|
||||||
|
for (IProject project : affectedProjects) {
|
||||||
|
refreshProjectTree(project);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -393,11 +326,7 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis
|
||||||
* @since 7.1
|
* @since 7.1
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(final CProjectDescriptionEvent event) {
|
public void handleEvent(CProjectDescriptionEvent event) {
|
||||||
Display display = Display.getDefault();
|
|
||||||
display.asyncExec(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
ICDescriptionDelta delta = event.getDefaultSettingCfgDelta();
|
ICDescriptionDelta delta = event.getDefaultSettingCfgDelta();
|
||||||
if (delta==null)
|
if (delta==null)
|
||||||
return;
|
return;
|
||||||
|
@ -408,19 +337,18 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis
|
||||||
|
|
||||||
IProject project = null;
|
IProject project = null;
|
||||||
ICSettingObject setting = delta.getOldSetting();
|
ICSettingObject setting = delta.getOldSetting();
|
||||||
if (setting==null)
|
if (setting == null) {
|
||||||
setting = delta.getNewSetting();
|
setting = delta.getNewSetting();
|
||||||
|
}
|
||||||
|
|
||||||
if (setting instanceof ICConfigurationDescription)
|
if (setting instanceof ICConfigurationDescription) {
|
||||||
project = ((ICConfigurationDescription) setting).getProjectDescription().getProject();
|
project = ((ICConfigurationDescription) setting).getProjectDescription().getProject();
|
||||||
|
if (project != null) {
|
||||||
if (project!=null)
|
// refresh source roots under the project
|
||||||
viewer.refresh(project);
|
refreshProjectTree(project);
|
||||||
else
|
}
|
||||||
viewer.refresh();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue