final boolean hasRename = numMovedFrom > 0 && numMovedTo > 0;
Runnable addAndRemove = new Runnable() {
public void run() {
if (viewer instanceof AbstractTreeViewer) {
AbstractTreeViewer treeViewer = (AbstractTreeViewer) viewer;
// Disable redraw until the operation is finished so we don't
// get a flash of both the new and old item (in the case of
// rename)
// Only do this if we're both adding and removing files (the
// rename case)
if (hasRename) {
treeViewer.getControl().setRedraw(false);
}
try {
Set<IProject> notifyRebuilt = new HashSet<IProject>();
//now, we have to make a bridge among the tree and
//the python model (so, if some element is removed,
//we have to create an actual representation for it)
if (addedObjects.length > 0) {
treeViewer.add(resource, addedObjects);
for (Object object : addedObjects) {
if (object instanceof IResource) {
IResource rem = (IResource) object;
Object remInPythonModel = getResourceInPythonModel(rem, true);
if (remInPythonModel instanceof PythonSourceFolder) {
notifyRebuilt.add(rem.getProject());
}
}
}
}
if (removedObjects.length > 0) {
treeViewer.remove(removedObjects);
for (Object object : removedObjects) {
if (object instanceof IResource) {
IResource rem = (IResource) object;
Object remInPythonModel = getResourceInPythonModel(rem, true);
if (remInPythonModel instanceof PythonSourceFolder) {
notifyRebuilt.add(rem.getProject());
}
}
}
}
for (IProject project : notifyRebuilt) {
PythonNature nature = PythonNature.getPythonNature(project);
if (nature != null) {
notifyPythonPathRebuilt(project, nature);
}
}
} finally {
if (hasRename) {
treeViewer.getControl().setRedraw(true);
}
}
} else {
((StructuredViewer) viewer).refresh(resource);
}