Search in sources :

Example 11 with PythonSourceFolder

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);
}
Also used : IFile(org.eclipse.core.resources.IFile) IPythonNature(org.python.pydev.core.IPythonNature) PythonNature(org.python.pydev.plugin.nature.PythonNature) AbstractTreeViewer(org.eclipse.jface.viewers.AbstractTreeViewer) IProject(org.eclipse.core.resources.IProject) PythonSourceFolder(org.python.pydev.navigator.elements.PythonSourceFolder) Control(org.eclipse.swt.widgets.Control) StructuredViewer(org.eclipse.jface.viewers.StructuredViewer) IResource(org.eclipse.core.resources.IResource) IResourceDelta(org.eclipse.core.resources.IResourceDelta) HashSet(java.util.HashSet)

Example 12 with PythonSourceFolder

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();
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) IWorkingSet(org.eclipse.ui.IWorkingSet) PythonNature(org.python.pydev.plugin.nature.PythonNature) FolderStub(org.python.pydev.shared_core.resource_stubs.FolderStub) PythonSourceFolder(org.python.pydev.navigator.elements.PythonSourceFolder) PipelinedShapeModification(org.eclipse.ui.navigator.PipelinedShapeModification) File(java.io.File) HashSet(java.util.HashSet)

Example 13 with PythonSourceFolder

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;
}
Also used : IContainer(org.eclipse.core.resources.IContainer) IWrappedResource(org.python.pydev.navigator.elements.IWrappedResource) PythonSourceFolder(org.python.pydev.navigator.elements.PythonSourceFolder)

Example 14 with PythonSourceFolder

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);
    }
}
Also used : FastStack(org.python.pydev.shared_core.structure.FastStack) IFile(org.eclipse.core.resources.IFile) PythonFolder(org.python.pydev.navigator.elements.PythonFolder) IContainer(org.eclipse.core.resources.IContainer) PythonFile(org.python.pydev.navigator.elements.PythonFile) IWrappedResource(org.python.pydev.navigator.elements.IWrappedResource) PythonSourceFolder(org.python.pydev.navigator.elements.PythonSourceFolder) IProject(org.eclipse.core.resources.IProject) IResource(org.eclipse.core.resources.IResource) IFolder(org.eclipse.core.resources.IFolder)

Example 15 with PythonSourceFolder

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;
    }
}
Also used : PythonNature(org.python.pydev.plugin.nature.PythonNature) IContainer(org.eclipse.core.resources.IContainer) PythonSourceFolder(org.python.pydev.navigator.elements.PythonSourceFolder) IProject(org.eclipse.core.resources.IProject) IWrappedResource(org.python.pydev.navigator.elements.IWrappedResource) IFolder(org.eclipse.core.resources.IFolder)

Aggregations

PythonSourceFolder (org.python.pydev.navigator.elements.PythonSourceFolder)17 PythonNature (org.python.pydev.plugin.nature.PythonNature)10 HashSet (java.util.HashSet)9 IProject (org.eclipse.core.resources.IProject)8 IFolder (org.eclipse.core.resources.IFolder)6 IWorkingSet (org.eclipse.ui.IWorkingSet)6 IWrappedResource (org.python.pydev.navigator.elements.IWrappedResource)6 File (java.io.File)5 Set (java.util.Set)5 IContainer (org.eclipse.core.resources.IContainer)5 IResource (org.eclipse.core.resources.IResource)5 PythonFolder (org.python.pydev.navigator.elements.PythonFolder)5 IFile (org.eclipse.core.resources.IFile)4 PythonProjectSourceFolder (org.python.pydev.navigator.elements.PythonProjectSourceFolder)4 IPath (org.eclipse.core.runtime.IPath)3 PipelinedShapeModification (org.eclipse.ui.navigator.PipelinedShapeModification)3 FolderStub (org.python.pydev.shared_core.resource_stubs.FolderStub)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 IPythonNature (org.python.pydev.core.IPythonNature)2