Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlain Magloire2004-02-18 12:09:01 -0500
committerAlain Magloire2004-02-18 12:09:01 -0500
commit9ce371db1594ab3d10b4b471fa5501ec4ad33784 (patch)
tree375b90df2034c0be205eee67a5a5a17782360d2d
parentdb13f377f51cbcfa4e806215eb9d3698a9ae7bb2 (diff)
downloadorg.eclipse.cdt-9ce371db1594ab3d10b4b471fa5501ec4ad33784.tar.gz
org.eclipse.cdt-9ce371db1594ab3d10b4b471fa5501ec4ad33784.tar.xz
org.eclipse.cdt-9ce371db1594ab3d10b4b471fa5501ec4ad33784.zip
Patch from Thomas dealing with the OpenIncludeAction.
-rw-r--r--core/org.eclipse.cdt.ui/ChangeLog11
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java161
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java2
3 files changed, 157 insertions, 17 deletions
diff --git a/core/org.eclipse.cdt.ui/ChangeLog b/core/org.eclipse.cdt.ui/ChangeLog
index 3f7574ad18..80053fac86 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 cf070c4a7b..4e379b8375 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 70fe9d0ccf..5f1b5941b4 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;
}

Back to the top