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 d5991c87322..b1cc659a209 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.ui.actions; @@ -17,7 +18,12 @@ import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.cdt.internal.ui.util.EditorUtility; +import org.eclipse.cdt.internal.ui.viewsupport.CElementLabels; +import org.eclipse.cdt.internal.ui.viewsupport.CUILabelProvider; + import org.eclipse.cdt.ui.CElementLabelProvider; + +import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorPart; @@ -65,7 +71,22 @@ public class OpenActionUtil { * Utility method that can be called by subclassers. */ public static ICElement selectCElement(ICElement[] elements, Shell shell, String title, String message) { - + return selectCElement(elements, shell, title, message, 0, 0); + } + + /** + * Shows a dialog for resolving an ambigous C element. + * @see CElementLabels + * @param elements an array of ambigous elements. + * @param shell parent shell for showing the dialog + * @param title title of the dialog + * @param message message to be shown in the dialog + * @param textFlags text flags to change the label provider + * @param imageFlags image flags to change the label provider + * @return the selected element or null + * @since 4.0 + */ + public static ICElement selectCElement(ICElement[] elements, Shell shell, String title, String message, int textFlags, int imageFlags) { int nResults= elements.length; if (nResults == 0) @@ -74,11 +95,15 @@ public class OpenActionUtil { if (nResults == 1) return elements[0]; - int flags= CElementLabelProvider.SHOW_DEFAULT - | CElementLabelProvider.SHOW_QUALIFIED; -// | CElementLabelProvider.SHOW_ROOT; + ILabelProvider labelProvider; + if (textFlags == 0 && imageFlags == 0) { + labelProvider= new CElementLabelProvider(CElementLabelProvider.SHOW_DEFAULT | CElementLabelProvider.SHOW_QUALIFIED); + } + else { + labelProvider= new CUILabelProvider(textFlags, imageFlags); + } - ElementListSelectionDialog dialog= new ElementListSelectionDialog(shell, new CElementLabelProvider(flags)); + ElementListSelectionDialog dialog= new ElementListSelectionDialog(shell, labelProvider); dialog.setTitle(title); dialog.setMessage(message); dialog.setElements(elements); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.java index 8c701dd4f31..bf4383f2a3c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.java @@ -15,6 +15,8 @@ import org.eclipse.osgi.util.NLS; public class CHMessages extends NLS { private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.ui.callhierarchy.CHMessages"; //$NON-NLS-1$ + public static String CallHierarchyUI_label; + public static String CallHierarchyUI_selectMessage; public static String CHHistoryListAction_HistoryDialog_title; public static String CHHistoryListAction_HistoryList_label; public static String CHHistoryListAction_OpenHistory_label; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.properties index 94ddd6bd240..77ec4eaef15 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.properties @@ -32,3 +32,5 @@ CHHistoryListAction_OpenHistory_label=Open History... CHHistoryDropDownAction_ShowHistoryList_tooltip=Show History List OpenCallHierarchyAction_label=Open Call H&ierarchy (work in progress) OpenCallHierarchyAction_tooltip=Open Call Hierarchy (work in progress) +CallHierarchyUI_label=Open Call Hierarchy +CallHierarchyUI_selectMessage=Select one element from the list diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHViewPart.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHViewPart.java index 9c7cdc7b4d9..fe3bdcfff9a 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHViewPart.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHViewPart.java @@ -122,12 +122,12 @@ public class CHViewPart extends ViewPart { private Action fRefreshAction; private Action fHistoryAction; private Action fShowReference; + private Action fOpenElement; // action groups private OpenViewActionGroup fOpenViewActionGroup; private SelectionSearchGroup fSelectionSearchGroup; private CRefactoringActionGroup fRefactoringActionGroup; - private Action fOpenElement; private WorkingSetFilterUI fFilterUI; @@ -461,6 +461,10 @@ public class CHViewPart extends ViewPart { // setup action bar // global action hooks IActionBars actionBars = getViewSite().getActionBars(); + fRefactoringActionGroup.fillActionBars(actionBars); + fOpenViewActionGroup.fillActionBars(actionBars); + fSelectionSearchGroup.fillActionBars(actionBars); + actionBars.setGlobalActionHandler(ActionFactory.NEXT.getId(), fNextAction); actionBars.setGlobalActionHandler(ActionFactory.PREVIOUS.getId(), fPreviousAction); actionBars.setGlobalActionHandler(ActionFactory.REFRESH.getId(), fRefreshAction); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java index a6b58ad8b84..fb551cf9655 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java @@ -12,13 +12,30 @@ package org.eclipse.cdt.internal.ui.callhierarchy; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ILanguage; +import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.internal.ui.actions.OpenActionUtil; +import org.eclipse.cdt.internal.ui.editor.CEditor; +import org.eclipse.cdt.internal.ui.missingapi.CIndexQueries; import org.eclipse.cdt.internal.ui.util.ExceptionHandler; +import org.eclipse.cdt.internal.ui.viewsupport.CElementLabels; public class CallHierarchyUI { @@ -41,4 +58,91 @@ public class CallHierarchyUI { return null; } + private static CHViewPart openInViewPart(IWorkbenchWindow window, ICElement[] input) { + ICElement elem = null; + switch (input.length) { + case 0: + break; + case 1: + elem = input[0]; + break; + default: + elem = OpenActionUtil.selectCElement(input, window.getShell(), + CHMessages.CallHierarchyUI_label, CHMessages.CallHierarchyUI_selectMessage, + CElementLabels.ALL_DEFAULT | CElementLabels.MF_POST_FILE_QUALIFIED, 0); + break; + } + if (elem != null) { + return openInViewPart(window, elem); + } + return null; + } + + public static void open(final CEditor editor, final ITextSelection sel) { + if (editor != null) { + final ICProject project= editor.getInputCElement().getCProject(); + final IEditorInput editorInput = editor.getEditorInput(); + final Display display= Display.getCurrent(); + + Job job= new Job(CHMessages.CallHierarchyUI_label) { + protected IStatus run(IProgressMonitor monitor) { + try { + final ICElement[] elems= findDefinitions(); + if (elems != null && elems.length > 0) { + display.asyncExec(new Runnable() { + public void run() { + openInViewPart(editor.getSite().getWorkbenchWindow(), elems); + }}); + } + return Status.OK_STATUS; + } + catch (CoreException e) { + return e.getStatus(); + } + } + + private ICElement[] findDefinitions() throws CoreException { + CIndexQueries index= CIndexQueries.getInstance(); + IASTName name= getSelectedName(editorInput, sel); + if (name != null) { + if (name.isDefinition()) { + ICElement elem= index.findDefinition(project, name); + if (elem != null) { + return new ICElement[]{elem}; + } + } + else { + ICElement[] elems= index.findAllDefinitions(project, name); + if (elems.length == 0) { + ICProject[] allProjects= CoreModel.getDefault().getCModel().getCProjects(); + elems= index.findAllDefinitions(allProjects, name); + } + return elems; + } + } + return null; + } + }; + job.setUser(true); + job.schedule(); + } + } + + private static IASTName getSelectedName(IEditorInput editorInput, ITextSelection selection) throws CoreException { + int selectionStart = selection.getOffset(); + int selectionLength = selection.getLength(); + + IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editorInput); + if (workingCopy == null) + return null; + + int options= ILanguage.AST_SKIP_ALL_HEADERS | ILanguage.AST_USE_INDEX; + IASTTranslationUnit ast = workingCopy.getLanguage().getASTTranslationUnit(workingCopy, options); + IASTName[] selectedNames = workingCopy.getLanguage().getSelectedNames(ast, selectionStart, selectionLength); + + if (selectedNames.length > 0 && selectedNames[0] != null) { // just right, only one name selected + return selectedNames[0]; + } + return null; + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/OpenCallHierarchyAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/OpenCallHierarchyAction.java index 168d9bfc4c1..adefdc0f43b 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/OpenCallHierarchyAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/OpenCallHierarchyAction.java @@ -21,17 +21,27 @@ import org.eclipse.cdt.core.model.IFunctionDeclaration; import org.eclipse.cdt.core.model.IVariableDeclaration; import org.eclipse.cdt.ui.actions.SelectionDispatchAction; +import org.eclipse.cdt.internal.ui.editor.CEditor; + public class OpenCallHierarchyAction extends SelectionDispatchAction { + private CEditor fEditor; + public OpenCallHierarchyAction(IWorkbenchSite site) { super(site); setText(CHMessages.OpenCallHierarchyAction_label); setToolTipText(CHMessages.OpenCallHierarchyAction_tooltip); } + public OpenCallHierarchyAction(CEditor editor) { + this(editor.getSite()); + fEditor= editor; + setEnabled(true); + } + public void run(ITextSelection sel) { - // mstodo run open call tree on editor. + CallHierarchyUI.open(fEditor, sel); } public void run(IStructuredSelection selection) { @@ -46,7 +56,7 @@ public class OpenCallHierarchyAction extends SelectionDispatchAction { public void selectionChanged(ITextSelection sel) { } - + public void selectionChanged(IStructuredSelection selection) { if (selection.isEmpty()) { setEnabled(false); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java index 792d2bca15e..40492c59205 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java @@ -89,6 +89,7 @@ import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IActionBars; import org.eclipse.ui.IEditorActionBarContributor; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; @@ -132,6 +133,7 @@ import org.eclipse.cdt.refactoring.actions.CRefactoringActionGroup; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.IWorkingCopyManager; import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.cdt.ui.actions.OpenViewActionGroup; import org.eclipse.cdt.ui.actions.ShowInCViewAction; import org.eclipse.cdt.ui.text.ICPartitions; import org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider; @@ -510,6 +512,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS private ActionGroup fSelectionSearchGroup; private ActionGroup fTextSearchGroup; private CRefactoringActionGroup fRefactoringActionGroup; + private ActionGroup fOpenInViewGroup; /** Action which shows selected element in CView. */ private ShowInCViewAction fShowInCViewAction; @@ -985,6 +988,11 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS fRefactoringActionGroup = null; } + if (fOpenInViewGroup != null) { + fOpenInViewGroup.dispose(); + fOpenInViewGroup = null; + } + if (fEditorSelectionChangedListener != null) { fEditorSelectionChangedListener.uninstall(getSelectionProvider()); fEditorSelectionChangedListener= null; @@ -1124,6 +1132,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS fSelectionSearchGroup = new SelectionSearchGroup(this); fTextSearchGroup= new TextSearchGroup(this); fRefactoringActionGroup= new CRefactoringActionGroup(this); + fOpenInViewGroup= new OpenViewActionGroup(this); } /** @@ -1157,6 +1166,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS fSelectionSearchGroup.fillContextMenu(menu); fTextSearchGroup.fillContextMenu(menu); fRefactoringActionGroup.fillContextMenu(menu); + fOpenInViewGroup.fillContextMenu(menu); } /** @@ -2242,4 +2252,12 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS } } + /** + * Called whenever the editor is activated and allows for registering + * action handlers. + */ + public void fillActionBars(IActionBars actionBars) { + fOpenInViewGroup.fillActionBars(actionBars); + } + } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorActionContributor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorActionContributor.java index ef05572321d..f97afc2e2eb 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorActionContributor.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorActionContributor.java @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * QNX Software System + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.ui.editor; @@ -200,6 +201,12 @@ public class CEditorActionContributor extends TextEditorActionContributor { fAddInclude.setAction(getAction(textEditor, "AddIncludeOnSelection")); //$NON-NLS-1$ fOpenOnSelection.setAction(getAction(textEditor, "OpenOnSelection")); //$NON-NLS-1$ fFormatter.setAction(getAction(textEditor, "Format")); //$NON-NLS-1$ + + if (part instanceof CEditor) { + CEditor cEditor= (CEditor) part; + cEditor.fillActionBars(getActionBars()); + } + } /* diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/missingapi/CIndexQueries.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/missingapi/CIndexQueries.java index 630296bf4aa..9cadae1352f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/missingapi/CIndexQueries.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/missingapi/CIndexQueries.java @@ -393,7 +393,7 @@ public class CIndexQueries { ArrayList result= new ArrayList(defs.length); for (int i = 0; i < defs.length; i++) { IASTName defName = defs[i]; - ICElement elem= findEnclosingElement(project, (PDOMName) defName); + ICElement elem= findEnclosingElement(project, defName); if (elem != null) { result.add(elem); } @@ -403,16 +403,23 @@ public class CIndexQueries { return EMPTY_ELEMENTS; } - private ICElement findEnclosingElement(ICProject project, PDOMName declName) { + private ICElement findEnclosingElement(ICProject project, IASTName declName) { ITranslationUnit tu= toTranslationUnit(project, declName); if (tu != null) { - // mstodo use correct timestamp - // PDOMFile file= declName.getFile(); - long timestamp= tu.getPath().toFile().lastModified(); - IPositionConverter pc= CCorePlugin.getPositionTrackerManager().findPositionConverter(tu.getPath(), timestamp); - int offset= declName.getNodeOffset(); - if (pc != null) { - offset= pc.historicToActual(new Region(offset, 0)).getOffset(); + int offset= 0; + if (declName instanceof PDOMName) { + PDOMName pname= (PDOMName) declName; + offset= pname.getNodeOffset(); + // mstodo use correct timestamp + // PDOMFile file= pname.getFile(); + long timestamp= tu.getPath().toFile().lastModified(); + IPositionConverter pc= CCorePlugin.getPositionTrackerManager().findPositionConverter(tu.getPath(), timestamp); + if (pc != null) { + offset= pc.historicToActual(new Region(offset, 0)).getOffset(); + } + } + else { + offset= declName.getFileLocation().getNodeOffset(); } return findElement(tu, offset, true); } @@ -433,6 +440,10 @@ public class CIndexQueries { } public ICElement findDefinition(ICProject project, IASTName name) { + if (name.isDefinition()) { + return findEnclosingElement(project, name); + } + PDOM pdom; try { pdom = (PDOM) CCorePlugin.getPDOMManager().getPDOM(project); @@ -463,7 +474,7 @@ public class CIndexQueries { if (defs != null) { for (int i = 0; i < defs.length; i++) { IASTName defName = defs[i]; - ICElement elem= findEnclosingElement(project, (PDOMName) defName); + ICElement elem= findEnclosingElement(project, defName); if (elem != null) { return elem; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/OpenViewActionGroup.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/OpenViewActionGroup.java index 91e231f9fe0..f15a02ccd9f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/OpenViewActionGroup.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/OpenViewActionGroup.java @@ -100,8 +100,9 @@ public class OpenViewActionGroup extends ActionGroup { // fOpenTypeHierarchy.setActionDefinitionId(ICEditorActionDefinitionIds.OPEN_TYPE_HIERARCHY); // part.setAction("OpenTypeHierarchy", fOpenTypeHierarchy); //$NON-NLS-1$ - fOpenCallHierarchy= new OpenCallHierarchyAction(part.getSite()); + fOpenCallHierarchy= new OpenCallHierarchyAction(part); fOpenCallHierarchy.setActionDefinitionId(ICEditorActionDefinitionIds.OPEN_CALL_HIERARCHY); + part.setAction("OpenCallHierarchy", fOpenCallHierarchy); //$NON-NLS-1$ initialize(part.getEditorSite()); } @@ -168,8 +169,9 @@ public class OpenViewActionGroup extends ActionGroup { } // appendToGroup(menu, fOpenSuperImplementation); IStructuredSelection selection= getStructuredSelection(); - if (fOpenPropertiesDialog != null && fOpenPropertiesDialog.isEnabled() && selection != null &&fOpenPropertiesDialog.isApplicableForSelection(selection)) + if (fOpenPropertiesDialog != null && fOpenPropertiesDialog.isEnabled() && selection != null &&fOpenPropertiesDialog.isApplicableForSelection(selection)) { menu.appendToGroup(IContextMenuConstants.GROUP_PROPERTIES, fOpenPropertiesDialog); + } } /* @@ -181,7 +183,9 @@ public class OpenViewActionGroup extends ActionGroup { // provider.removeSelectionChangedListener(fOpenExternalJavadoc); // provider.removeSelectionChangedListener(fOpenTypeHierarchy); provider.removeSelectionChangedListener(fOpenCallHierarchy); - fOpenPropertiesDialog.dispose(); + if (fOpenPropertiesDialog != null) { + fOpenPropertiesDialog.dispose(); + } super.dispose(); } @@ -190,7 +194,9 @@ public class OpenViewActionGroup extends ActionGroup { // actionBars.setGlobalActionHandler(JdtActionConstants.OPEN_EXTERNAL_JAVA_DOC, fOpenExternalJavadoc); // actionBars.setGlobalActionHandler(CdtActionConstants.OPEN_TYPE_HIERARCHY, fOpenTypeHierarchy); actionBars.setGlobalActionHandler(CdtActionConstants.OPEN_CALL_HIERARCHY, fOpenCallHierarchy); - actionBars.setGlobalActionHandler(ActionFactory.PROPERTIES.getId(), fOpenPropertiesDialog); + if (fOpenPropertiesDialog != null) { + actionBars.setGlobalActionHandler(ActionFactory.PROPERTIES.getId(), fOpenPropertiesDialog); + } } private IStructuredSelection getStructuredSelection() { @@ -204,8 +210,8 @@ public class OpenViewActionGroup extends ActionGroup { } public static boolean canActionBeAdded(ISelection selection) { - if(selection instanceof ITextSelection) { - return (((ITextSelection)selection).getLength() > 0); + if (selection instanceof ITextSelection) { + return true; } return getElement(selection) != null; }