diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/OpenActionUtil.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/OpenActionUtil.java index fb7ee19ae8d..defff447f50 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/OpenActionUtil.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/OpenActionUtil.java @@ -15,13 +15,14 @@ package org.eclipse.cdt.internal.ui.actions; import java.util.ArrayList; import java.util.List; +import org.eclipse.core.runtime.IPath; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.PartInitException; -import org.eclipse.ui.dialogs.ElementListSelectionDialog; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.ICElement; @@ -29,6 +30,7 @@ import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.cdt.ui.CElementLabelProvider; import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.internal.ui.dialogs.ElementListSelectionDialog; import org.eclipse.cdt.internal.ui.util.EditorUtility; import org.eclipse.cdt.internal.ui.viewsupport.CElementLabels; import org.eclipse.cdt.internal.ui.viewsupport.CUILabelProvider; @@ -103,12 +105,12 @@ public class OpenActionUtil { ILabelProvider labelProvider; if (textFlags == 0 && imageFlags == 0) { labelProvider= new CElementLabelProvider(CElementLabelProvider.SHOW_DEFAULT | CElementLabelProvider.SHOW_QUALIFIED); - } - else { + } else { labelProvider= new CUILabelProvider(textFlags, imageFlags); } - ElementListSelectionDialog dialog= new ElementListSelectionDialog(shell, labelProvider) { + // TODO: Use CDT's ElementListSelectionDialog as in selectPath(). + org.eclipse.ui.dialogs.ElementListSelectionDialog dialog= new org.eclipse.ui.dialogs.ElementListSelectionDialog(shell, labelProvider) { @Override protected IDialogSettings getDialogBoundsSettings() { IDialogSettings settings = CUIPlugin.getDefault().getDialogSettings(); @@ -135,5 +137,35 @@ public class OpenActionUtil { } } return null; - } + } + + /** + * Shows a dialog for resolving an ambiguous path. + * @param paths an array of ambiguous paths + * @param title title of the dialog + * @param message message to be shown in the dialog + * @return the selected path or null + */ + public static IPath selectPath(List paths, String title, String message) { + ILabelProvider renderer= new LabelProvider() { + @Override + public String getText(Object element) { + if (element instanceof IPath) { + IPath file= (IPath)element; + return file.lastSegment() + " - " + file.toString(); //$NON-NLS-1$ + } + return super.getText(element); + } + }; + + ElementListSelectionDialog dialog= new ElementListSelectionDialog(CUIPlugin.getActiveWorkbenchShell(), renderer, false, false); + dialog.setTitle(title); + dialog.setMessage(message); + dialog.setElements(paths); + + if (dialog.open() == Window.OK) { + return (IPath) dialog.getSelectedElement(); + } + return null; + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CElementIncludeResolver.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CElementIncludeResolver.java index 1475fc464d2..357fe0f1374 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CElementIncludeResolver.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CElementIncludeResolver.java @@ -10,6 +10,7 @@ package org.eclipse.cdt.internal.ui.editor; import java.io.File; import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; @@ -25,11 +26,6 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.viewers.ILabelProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.window.Window; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.MessageBox; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.IInclude; @@ -37,19 +33,16 @@ import org.eclipse.cdt.core.parser.ExtendedScannerInfo; import org.eclipse.cdt.core.parser.IExtendedScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfoProvider; -import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.utils.PathUtil; import org.eclipse.cdt.utils.UNCPathConverter; import org.eclipse.cdt.internal.core.resources.ResourceLookup; -import org.eclipse.cdt.internal.ui.dialogs.ElementListSelectionDialog; - /** * Handles resolution of an include represented as a CElement (IInclude). */ public class CElementIncludeResolver { - public static IPath resolveInclude(IInclude include) throws CoreException { + public static List resolveInclude(IInclude include) throws CoreException { IResource res = include.getUnderlyingResource(); ArrayList filesFound = new ArrayList(4); String fullFileName= include.getFullFileName(); @@ -107,26 +100,9 @@ public class CElementIncludeResolver { } } } - IPath fileToOpen; - int nElementsFound= filesFound.size(); - if (nElementsFound == 0) { - noElementsFound(); - fileToOpen= null; - } else if (nElementsFound == 1) { - fileToOpen= filesFound.get(0); - } else { - fileToOpen= chooseFile(filesFound); - } - return fileToOpen; + return filesFound; } - private static void noElementsFound() { - MessageBox errorMsg = new MessageBox(CUIPlugin.getActiveWorkbenchShell(), SWT.ICON_ERROR | SWT.OK); - errorMsg.setText(CUIPlugin.getResourceString("OpenIncludeAction.error")); //$NON-NLS-1$ - errorMsg.setMessage (CUIPlugin.getResourceString("OpenIncludeAction.error.description")); //$NON-NLS-1$ - errorMsg.open(); - } - private static void findFile(String[] includePaths, String name, ArrayList list) throws CoreException { // in case it is an absolute path @@ -184,29 +160,6 @@ public class CElementIncludeResolver { }, 0); } - private static IPath chooseFile(ArrayList filesFound) { - ILabelProvider renderer= new LabelProvider() { - @Override - public String getText(Object element) { - if (element instanceof IPath) { - IPath file= (IPath)element; - return file.lastSegment() + " - " + file.toString(); //$NON-NLS-1$ - } - return super.getText(element); - } - }; - - ElementListSelectionDialog dialog= new ElementListSelectionDialog(CUIPlugin.getActiveWorkbenchShell(), renderer, false, false); - dialog.setTitle(CUIPlugin.getResourceString(OpenIncludeAction.DIALOG_TITLE)); - dialog.setMessage(CUIPlugin.getResourceString(OpenIncludeAction.DIALOG_MESSAGE)); - dialog.setElements(filesFound); - - if (dialog.open() == Window.OK) { - return (IPath) dialog.getSelectedElement(); - } - return null; - } - /** * Returns the path as is, if it points to a workspace resource. If the path * does not point to a workspace resource, but there are linked workspace 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 7ea163056ea..5ef93fdadf3 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,12 +23,15 @@ import org.eclipse.jface.action.Action; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.MessageBox; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.IInclude; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.internal.ui.CPluginImages; +import org.eclipse.cdt.internal.ui.actions.OpenActionUtil; import org.eclipse.cdt.internal.ui.util.EditorUtility; @@ -36,8 +39,8 @@ public class OpenIncludeAction extends Action { private static final String PREFIX= "OpenIncludeAction."; //$NON-NLS-1$ - static final String DIALOG_TITLE= PREFIX + "dialog.title"; //$NON-NLS-1$ - static final String DIALOG_MESSAGE= PREFIX + "dialog.message"; //$NON-NLS-1$ + private static final String DIALOG_TITLE= PREFIX + "dialog.title"; //$NON-NLS-1$ + private static final String DIALOG_MESSAGE= PREFIX + "dialog.message"; //$NON-NLS-1$ private ISelectionProvider fSelectionProvider; @@ -58,15 +61,39 @@ public class OpenIncludeAction extends Action { return; } try { - IPath fileToOpen = CElementIncludeResolver.resolveInclude(include); + List filesFound = CElementIncludeResolver.resolveInclude(include); + int nElementsFound= filesFound.size(); + if (nElementsFound == 0) { + noElementsFound(); + return; + } + + IPath fileToOpen; + if (nElementsFound == 1) { + fileToOpen= filesFound.get(0); + } else { + fileToOpen= chooseFile(filesFound); + } if (fileToOpen != null) { EditorUtility.openInEditor(fileToOpen, include); - } + } } catch (CoreException e) { CUIPlugin.log(e.getStatus()); } } - + + private static void noElementsFound() { + MessageBox errorMsg = new MessageBox(CUIPlugin.getActiveWorkbenchShell(), SWT.ICON_ERROR | SWT.OK); + errorMsg.setText(CUIPlugin.getResourceString("OpenIncludeAction.error")); //$NON-NLS-1$ + errorMsg.setMessage (CUIPlugin.getResourceString("OpenIncludeAction.error.description")); //$NON-NLS-1$ + errorMsg.open(); + } + + private static IPath chooseFile(List filesFound) { + return OpenActionUtil.selectPath(filesFound, CUIPlugin.getResourceString(DIALOG_TITLE), + CUIPlugin.getResourceString(DIALOG_MESSAGE)); + } + private static IInclude getIncludeStatement(ISelection sel) { if (!sel.isEmpty() && sel instanceof IStructuredSelection) { List list= ((IStructuredSelection)sel).toList(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java index ab38d6d7f51..6ec5448a919 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java @@ -106,6 +106,7 @@ import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable; import org.eclipse.cdt.internal.core.model.ext.CElementHandleFactory; import org.eclipse.cdt.internal.core.model.ext.ICElementHandle; +import org.eclipse.cdt.internal.ui.actions.OpenActionUtil; import org.eclipse.cdt.internal.ui.actions.SelectionConverter; import org.eclipse.cdt.internal.ui.editor.ASTProvider; import org.eclipse.cdt.internal.ui.editor.CEditorMessages; @@ -175,12 +176,8 @@ class OpenDeclarationsJob extends Job implements ASTRunnable { if (element instanceof IInclude) { // If the cursor is over an include, open the referenced file. IInclude include = (IInclude) element; - IPath fileToOpen = CElementIncludeResolver.resolveInclude(include); - if (fileToOpen != null) { - openInclude(fileToOpen); - return Status.OK_STATUS; - } - fAction.reportIncludeLookupFailure(include.getFullFileName()); + List paths = CElementIncludeResolver.resolveInclude(include); + openInclude(paths, include.getIncludeName()); return Status.OK_STATUS; } else { // Otherwise, lookup the selected word in the index. @@ -779,26 +776,43 @@ class OpenDeclarationsJob extends Job implements ASTRunnable { if (incStmt.isResolved()) name = incStmt.getPath(); - IPath path = null; + List paths = null; if (name != null) { - path = new Path(name); + paths = new ArrayList<>(); + paths.add(new Path(name)); } else if (!incStmt.isActive()) { // Includes inside inactive preprocessor branches will not be resolved in the AST. // For these, attempt resolving the include via the C model as a fallback. try { ICElement element = SelectionConverter.getElementAtOffset(fTranslationUnit, fTextSelection); if (element instanceof IInclude) { - path = CElementIncludeResolver.resolveInclude((IInclude) element); + paths = CElementIncludeResolver.resolveInclude((IInclude) element); } } catch (CModelException e) { } catch (CoreException e) { } } - - if (path != null) { - openInclude(path); + + openInclude(paths, new String(incStmt.getName().toCharArray())); + } + + private void openInclude(List paths, String includeName) { + if (paths == null || paths.isEmpty()) { + fAction.reportIncludeLookupFailure(includeName); + } else if (paths.size() == 1) { + openInclude(paths.get(0)); } else { - fAction.reportIncludeLookupFailure(new String(incStmt.getName().toCharArray())); + runInUIThread(new Runnable() { + @Override + public void run() { + IPath selected = OpenActionUtil.selectPath(paths, + CEditorMessages.OpenDeclarationsAction_dialog_title, + CEditorMessages.OpenDeclarationsAction_selectMessage); + if (selected != null) { + openInclude(selected); + } + } + }); } }