diff options
author | Alain Magloire | 2004-02-18 17:09:01 +0000 |
---|---|---|
committer | Alain Magloire | 2004-02-18 17:09:01 +0000 |
commit | 9ce371db1594ab3d10b4b471fa5501ec4ad33784 (patch) | |
tree | 375b90df2034c0be205eee67a5a5a17782360d2d | |
parent | db13f377f51cbcfa4e806215eb9d3698a9ae7bb2 (diff) | |
download | org.eclipse.cdt-9ce371db1594ab3d10b4b471fa5501ec4ad33784.tar.gz org.eclipse.cdt-9ce371db1594ab3d10b4b471fa5501ec4ad33784.tar.xz org.eclipse.cdt-9ce371db1594ab3d10b4b471fa5501ec4ad33784.zip |
Patch from Thomas dealing with the OpenIncludeAction.
3 files changed, 157 insertions, 17 deletions
diff --git a/core/org.eclipse.cdt.ui/ChangeLog b/core/org.eclipse.cdt.ui/ChangeLog index 3f7574ad189..80053fac865 100644 --- a/core/org.eclipse.cdt.ui/ChangeLog +++ b/core/org.eclipse.cdt.ui/ChangeLog @@ -1,3 +1,14 @@ +2004-02-18 Alain Magloire + + Patch from Thomas Fletcher. + PR 52128: Where duplicate editors are opened for external include files + PR 46263: Where local headers residing in the current directory are not found. + PR 51355: Performance in searching a large project in the absence of + proper include information is poor. + + * src/org/eclipse/cdt/internal/ui/util/EditorUtility.java + * src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java + 2004-02-13 Bogdan Gheorghe Thomas' patch: Modified CCompletionProcessor to use FORCE_IMMEDIATE_SEARCH when requesting a dependency query/search. diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java index cf070c4a7bc..4e379b8375f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java @@ -23,6 +23,8 @@ import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceProxy; +import org.eclipse.core.resources.IResourceProxyVisitor; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; @@ -35,22 +37,29 @@ import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.window.Window; import org.eclipse.ui.IEditorDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IEditorRegistry; +import org.eclipse.ui.IStorageEditorInput; import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.internal.UIPlugin; public class OpenIncludeAction extends Action { - - private static final String PREFIX= "OpenIncludeAction."; private static final String DIALOG_TITLE= PREFIX + "dialog.title"; private static final String DIALOG_MESSAGE= PREFIX + "dialog.message"; private ISelectionProvider fSelectionProvider; - + private IResource fBaseResource; public OpenIncludeAction(ISelectionProvider provider) { + this(provider, null); + } + + public OpenIncludeAction(ISelectionProvider provider, IResource baseResource) { super(CUIPlugin.getResourceString(PREFIX + "label")); setDescription(CUIPlugin.getResourceString(PREFIX + "description")); setToolTipText(CUIPlugin.getResourceString(PREFIX + "tooltip")); @@ -58,6 +67,28 @@ public class OpenIncludeAction extends Action { CPluginImages.setImageDescriptors(this, CPluginImages.T_LCL, CPluginImages.IMG_MENU_OPEN_INCLUDE); fSelectionProvider= provider; + fBaseResource = baseResource; + } + + /** + * Sets the base resource which will be used as a reference to extract out include + * path information if the selected element does not already contain resource + * reference information. + * + * @param resource IResource used as a reference to extract include path information or null not to have one + */ + public void setBaseResource(IResource resource) { + fBaseResource = resource; + } + + /** + * Returns the base resource currently used as a reference to extract out include + * path information. + * + * @param resource IResource used to extract the information or null if there is no base resource + */ + public IResource getBaseResource() { + return fBaseResource; } public void run() { @@ -65,9 +96,20 @@ public class OpenIncludeAction extends Action { if (include == null) { return; } + + /* FIXME + * The information about whether this is a local include file or not + * a local include file is in the Include specific ICElement. Unfortunately + * while we know that, it isn't part of the public interface. For now we + * just assume that every header has the possibility of being local. + */ + boolean isLocal = true; try { IResource res = include.getUnderlyingResource(); + if(res == null) { + res = fBaseResource; + } ArrayList filesFound= new ArrayList(4); if (res != null) { IProject proj = res.getProject(); @@ -81,10 +123,18 @@ public class OpenIncludeAction extends Action { info = provider.getScannerInformation(proj); } if (info != null) { + //If the header is local, then look in the current location first String[] includePaths = info.getIncludePaths(); + + if(isLocal) { //Prepend our path at the start of this array + String [] newIncludePaths = new String[includePaths.length + 1]; + newIncludePaths[0] = res.getLocation().removeLastSegments(1).toOSString(); + System.arraycopy(includePaths, 0, newIncludePaths, 1, includePaths.length); + includePaths = newIncludePaths; + } + findFile(includePaths, includeName, filesFound); } else { - // Fall back and search the project findFile(proj, new Path(includeName), filesFound); } } @@ -103,7 +153,7 @@ public class OpenIncludeAction extends Action { IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(fileToOpen); if (file != null) { EditorUtility.openInEditor(file); - } else { + } else if(activateExistingOpenedExternalFile(fileToOpen) == false){ FileStorage storage = new FileStorage(null, fileToOpen); EditorUtility.openInEditor(storage); } @@ -114,28 +164,107 @@ public class OpenIncludeAction extends Action { CUIPlugin.getDefault().log(e.getStatus()); } } + + /** + * Check to see if this file has already been opened in another editor using an + * external file storage mechanism + * @param path IPath with the path of the external file which is being edited. + * @return true if an editor was found and activated, false otherwise + */ + private boolean activateExistingOpenedExternalFile(IPath path) { + IEditorReference [] editorRefs; + editorRefs = UIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences(); + + for(int i = 0; i < editorRefs.length; i++) { + IEditorPart editor = editorRefs[i].getEditor(true); + IEditorInput input = editor.getEditorInput(); + if(input instanceof IStorageEditorInput) { + IPath editorPath; + try { + editorPath = ((IStorageEditorInput)input).getStorage().getFullPath(); + } catch(Exception ex) { + editorPath = null; + } + if(editorPath != null && editorPath.equals(path)) { + UIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage().activate(editor); + return true; + } + } + } + + return false; + } - private void findFile(String[] includePaths, String name, ArrayList list) throws CoreException { + private void findFile(String[] includePaths, String name, ArrayList list) throws CoreException { for (int i = 0; i < includePaths.length; i++) { IPath path = new Path(includePaths[i] + "/" + name); File file = path.toFile(); - if (file.exists()) { + if (file.exists() && !list.contains(path)) { list.add(path); } } } - private void findFile(IContainer parent, IPath name, ArrayList list) throws CoreException { - IResource found= parent.findMember(name); - if (found != null && found.getType() == IResource.FILE) { - list.add(found.getLocation()); + private void findFile(IContainer parent, IPath name, final ArrayList list) throws CoreException { + final String lastSegment = name.lastSegment(); + if(lastSegment == null) { + return; } - IResource[] children= parent.members(); - for (int i= 0; i < children.length; i++) { - if (children[i] instanceof IContainer) { - findFile((IContainer)children[i], name, list); + + final IPath pathSegments = name.removeLastSegments(1); + + //We use the lastSegment as a fast key, but then make sure that we can match + //the rest of the segments (if they exist) so a path like: + //#include "subsystem/includefile.h" won't match with "a/b/c/includefile.h" + IResourceProxyVisitor visitor = new IResourceProxyVisitor() { + private boolean checkSegments(IPath sourceSegments, IPath targetSegments) { + if(sourceSegments == null) { + return true; + } + if(targetSegments == null) { + return false; + } + + int segmentCount = sourceSegments.segmentCount(); + int targetCount = targetSegments.segmentCount(); + if(segmentCount > targetCount) { + return false; + } + + for(int i = segmentCount - 1; i >= 0; i--) { + if(!sourceSegments.segment(i).equals(targetSegments.segment(--targetCount))) { + return false; + } + } + + return true; } - } + + public boolean visit(IResourceProxy proxy) throws CoreException { + String resourceName = proxy.getName(); + if(resourceName.equals(lastSegment)) { + IResource res = proxy.requestResource(); + if(!res.exists()) { + return true; + } + + IPath location = res.getLocation(); + if(list.contains(location)) { + return true; + } + + //Check segment match criteria to make sure we really match this entry + if(checkSegments(pathSegments, location.removeLastSegments(1)) != true) { + return true; + } + + list.add(location); + } + return true; + } + }; + + parent.accept(visitor, IResource.NONE); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java index 70fe9d0ccf8..5f1b5941b48 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java @@ -109,7 +109,7 @@ public class EditorUtility { if (file != null) { IWorkbenchPage p= CUIPlugin.getActivePage(); if (p != null) { - IEditorPart editorPart= p.openEditor(file, null, activate); + IEditorPart editorPart= p.openEditor(file, getEditorID(file.getName()), activate); initializeHighlightRange(editorPart); return editorPart; } |