use of org.python.pydev.navigator.elements.PythonSourceFolder in project Pydev by fabioz.
the class PythonBaseModelProvider method processDelta.
/**
* Process a resource delta. Add any runnables
*/
private void processDelta(final IResourceDelta delta, final Collection<Runnable> runnables) {
// he widget may have been destroyed
// by the time this is run. Check for this and do nothing if so.
Control ctrl = viewer.getControl();
if (ctrl == null || ctrl.isDisposed()) {
return;
}
// Get the affected resource
final IResource resource = delta.getResource();
// If any children have changed type, just do a full refresh of this
// parent,
// since a simple update on such children won't work,
// and trying to map the change to a remove and add is too dicey.
// The case is: folder A renamed to existing file B, answering yes to
// overwrite B.
IResourceDelta[] affectedChildren = delta.getAffectedChildren(IResourceDelta.CHANGED);
for (int i = 0; i < affectedChildren.length; i++) {
if ((affectedChildren[i].getFlags() & IResourceDelta.TYPE) != 0) {
runnables.add(getRefreshRunnable(resource));
return;
}
}
// Opening a project just affects icon, but we need to refresh when
// a project is closed because if child items have not yet been created
// in the tree we still need to update the item's children
int changeFlags = delta.getFlags();
if ((changeFlags & IResourceDelta.OPEN) != 0) {
if (resource.isAccessible()) {
runnables.add(getUpdateRunnable(resource));
} else {
runnables.add(getRefreshRunnable(resource));
return;
}
}
// Notice we don't care about F_CONTENT or F_MARKERS currently.
if ((changeFlags & (IResourceDelta.SYNC | IResourceDelta.TYPE | IResourceDelta.DESCRIPTION)) != 0) {
runnables.add(getUpdateRunnable(resource));
}
// Replacing a resource may affect its label and its children
if ((changeFlags & IResourceDelta.REPLACED) != 0) {
runnables.add(getRefreshRunnable(resource));
return;
}
// Replacing a resource may affect its label and its children
if ((changeFlags & (IResourceDelta.CHANGED | IResourceDelta.CONTENT)) != 0) {
if (resource instanceof IFile) {
IFile file = (IFile) resource;
if (PythonPathHelper.isValidSourceFile(file)) {
runnables.add(getRefreshRunnable(resource));
}
}
return;
}
// Handle changed children .
for (int i = 0; i < affectedChildren.length; i++) {
processDelta(affectedChildren[i], runnables);
}
// @issue several problems here:
// - should process removals before additions, to avoid multiple equal
// elements in viewer
// - Kim: processing removals before additions was the indirect cause of
// 44081 and its varients
// - Nick: no delta should have an add and a remove on the same element,
// so processing adds first is probably OK
// - using setRedraw will cause extra flashiness
// - setRedraw is used even for simple changes
// - to avoid seeing a rename in two stages, should turn redraw on/off
// around combined removal and addition
// - Kim: done, and only in the case of a rename (both remove and add
// changes in one delta).
IResourceDelta[] addedChildren = delta.getAffectedChildren(IResourceDelta.ADDED);
IResourceDelta[] removedChildren = delta.getAffectedChildren(IResourceDelta.REMOVED);
if (addedChildren.length == 0 && removedChildren.length == 0) {
return;
}
final IResource[] addedObjects;
final IResource[] removedObjects;
// Process additions before removals as to not cause selection
// preservation prior to new objects being added
// Handle added children. Issue one update for all insertions.
int numMovedFrom = 0;
int numMovedTo = 0;
if (addedChildren.length > 0) {
addedObjects = new IResource[addedChildren.length];
for (int i = 0; i < addedChildren.length; i++) {
final IResourceDelta addedChild = addedChildren[i];
addedObjects[i] = addedChild.getResource();
if ((addedChild.getFlags() & IResourceDelta.MOVED_FROM) != 0) {
++numMovedFrom;
}
}
} else {
addedObjects = EMPTY_RESOURCE_ARRAY;
}
// Handle removed children. Issue one update for all removals.
if (removedChildren.length > 0) {
removedObjects = new IResource[removedChildren.length];
for (int i = 0; i < removedChildren.length; i++) {
final IResourceDelta removedChild = removedChildren[i];
removedObjects[i] = removedChild.getResource();
if ((removedChild.getFlags() & IResourceDelta.MOVED_TO) != 0) {
++numMovedTo;
}
}
} else {
removedObjects = EMPTY_RESOURCE_ARRAY;
}
// heuristic test for items moving within same folder (i.e. renames)
final boolean hasRename = numMovedFrom > 0 && numMovedTo > 0;
Runnable addAndRemove = new Runnable() {
@Override
public void run() {
if (viewer instanceof AbstractTreeViewer) {
AbstractTreeViewer treeViewer = viewer;
// rename case)
if (hasRename) {
treeViewer.getControl().setRedraw(false);
}
try {
Set<IProject> notifyRebuilt = new HashSet<IProject>();
// 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);
}
}
};
runnables.add(addAndRemove);
}
use of org.python.pydev.navigator.elements.PythonSourceFolder in project Pydev by fabioz.
the class PythonModelProviderTest method testAddSourceFolderToSourceFolder.
public void testAddSourceFolderToSourceFolder() throws Exception {
final HashSet<String> pythonPathSet = new HashSet<String>();
pythonPathSet.add(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source");
String source2Folder = TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot/source2";
File f = new File(source2Folder);
if (f.exists()) {
f.delete();
}
// still not created!
pythonPathSet.add(source2Folder);
PythonNature nature = createNature(pythonPathSet);
project = new ProjectStub(new File(TestDependent.TEST_PYSRC_NAVIGATOR_LOC + "projroot"), nature, false);
provider = new PythonModelProvider();
Object[] children1 = provider.getChildren(project);
assertEquals(1, children1.length);
assertTrue(children1[0] instanceof PythonSourceFolder);
Set set = new HashSet();
f.mkdir();
try {
FolderStub source2FolderFile = new FolderStub(project, f);
set.add(source2FolderFile);
provider.interceptAdd(new PipelinedShapeModification(project, set));
assertEquals(1, set.size());
assertTrue(set.iterator().next() instanceof PythonSourceFolder);
} finally {
f.delete();
}
}
use of org.python.pydev.navigator.elements.PythonSourceFolder in project Pydev by fabioz.
the class PythonLabelProvider method checkIfValidPackageFolder.
/**
* Checks if the given folder is a valid package.
*/
private final boolean checkIfValidPackageFolder(final PythonFolder pythonFolder) {
String name = pythonFolder.getActualObject().getName();
if (!PythonPathHelper.isValidModuleLastPart(name)) {
return false;
}
IWrappedResource parentElement = pythonFolder.getParentElement();
while (parentElement != null) {
if (parentElement instanceof PythonSourceFolder) {
// gotten to the source folder: this one doesn't need to have an __init__.py
return true;
}
Object actualObject = parentElement.getActualObject();
if (!(actualObject instanceof IContainer)) {
return false;
}
IContainer iContainer = (IContainer) actualObject;
if (!PythonPathHelper.isValidModuleLastPart(iContainer.getName())) {
return false;
}
Object tempParent = parentElement.getParentElement();
if (!(tempParent instanceof IWrappedResource)) {
break;
}
parentElement = (IWrappedResource) tempParent;
}
return true;
}
use of org.python.pydev.navigator.elements.PythonSourceFolder in project Pydev by fabioz.
the class PythonModelProvider method convertToPythonElementsAddOrRemove.
/**
* Converts the shape modification to use Python elements.
* @param natureToSourcePathSet
*
* @param modification: the shape modification to convert
* @param isAdd: boolean indicating whether this convertion is happening in an add operation
*/
@SuppressWarnings("unchecked")
private void convertToPythonElementsAddOrRemove(PipelinedShapeModification modification, boolean isAdd, Map<PythonNature, Set<String>> natureToSourcePathSet) {
if (DEBUG) {
debug("Before", modification);
}
Object parent = modification.getParent();
if (parent instanceof IContainer) {
IContainer parentContainer = (IContainer) parent;
Object pythonParent = getResourceInPythonModel(parentContainer, true);
if (pythonParent instanceof IWrappedResource) {
IWrappedResource parentResource = (IWrappedResource) pythonParent;
modification.setParent(parentResource);
wrapChildren(parentResource, parentResource.getSourceFolder(), modification.getChildren(), isAdd, natureToSourcePathSet);
} else if (pythonParent == null) {
Object parentInWrap = parentContainer;
PythonSourceFolder sourceFolderInWrap = null;
// this may happen when a source folder is added or some element that still doesn't have it's parent in the model...
// so, we have to get the parent's parent until we actually 'know' that it is not in the model (or until we run
// out of parents to try)
// the case in which we reproduce this is Test 1 (described in the class)
FastStack<Object> found = new FastStack<Object>(20);
while (true) {
// add the current to the found
if (parentContainer == null) {
break;
}
found.push(parentContainer);
if (parentContainer instanceof IProject) {
// we got to the project without finding any part of a python model already there, so, let's see
// if any of the parts was actually a source folder (that was still not added)
tryCreateModelFromProject((IProject) parentContainer, found, natureToSourcePathSet);
// and now, if it was created, try to convert it to the python model (without any further add)
convertToPythonElementsUpdateOrRefresh(modification.getChildren());
return;
}
Object p = getResourceInPythonModel(parentContainer, true);
if (p instanceof IWrappedResource) {
IWrappedResource wrappedResource = (IWrappedResource) p;
sourceFolderInWrap = wrappedResource.getSourceFolder();
while (found.size() > 0) {
Object f = found.pop();
if (f instanceof IResource) {
// no need to create it if it's already in the model!
Object child = sourceFolderInWrap.getChild((IResource) f);
if (child != null && child instanceof IWrappedResource) {
wrappedResource = (IWrappedResource) child;
continue;
}
}
// creating is enough to add it to the model
if (f instanceof IFile) {
wrappedResource = new PythonFile(wrappedResource, (IFile) f, sourceFolderInWrap);
} else if (f instanceof IFolder) {
wrappedResource = new PythonFolder(wrappedResource, (IFolder) f, sourceFolderInWrap);
}
}
parentInWrap = wrappedResource;
break;
}
parentContainer = parentContainer.getParent();
}
wrapChildren(parentInWrap, sourceFolderInWrap, modification.getChildren(), isAdd, natureToSourcePathSet);
}
} else if (parent == null) {
wrapChildren(null, null, modification.getChildren(), isAdd, natureToSourcePathSet);
}
if (DEBUG) {
debug("After", modification);
}
}
use of org.python.pydev.navigator.elements.PythonSourceFolder in project Pydev by fabioz.
the class PythonModelProvider method tryCreateModelFromProject.
/**
* Given a Path from the 1st child of the project, will try to create that path in the python model.
* @param project the project
* @param found a stack so that the last element added is the leaf of the path we want to discover
* @param natureToSourcePathSet
*/
private void tryCreateModelFromProject(IProject project, FastStack<Object> found, Map<PythonNature, Set<String>> natureToSourcePathSet) {
PythonNature nature = PythonNature.getPythonNature(project);
if (nature == null) {
// if the python nature is not available, we won't have any python elements here
return;
}
Set<String> sourcePathSet = this.getSourcePathSet(natureToSourcePathSet, nature);
Object currentParent = project;
PythonSourceFolder pythonSourceFolder = null;
for (Iterator<Object> it = found.topDownIterator(); it.hasNext(); ) {
Object child = it.next();
if (child instanceof IFolder || child instanceof IProject) {
if (pythonSourceFolder == null) {
pythonSourceFolder = tryWrapSourceFolder(currentParent, (IContainer) child, sourcePathSet);
if (pythonSourceFolder != null) {
currentParent = pythonSourceFolder;
} else if (child instanceof IContainer) {
currentParent = child;
}
// we didn't, then the children will not be in the python model anyway)
continue;
}
}
if (pythonSourceFolder != null) {
IWrappedResource r = doWrap(currentParent, pythonSourceFolder, child, natureToSourcePathSet);
if (r != null) {
child = r;
}
}
currentParent = child;
}
}
Aggregations