1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-02 22:55:26 +02:00

Patch from Thomas dealing with the OpenIncludeAction.

This commit is contained in:
Alain Magloire 2004-02-18 17:09:01 +00:00
parent db13f377f5
commit 9ce371db15
3 changed files with 157 additions and 17 deletions

View file

@ -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.

View file

@ -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);
}

View file

@ -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;
}