| /******************************************************************************* |
| * Copyright (c) 2000, 2007 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| |
| * (report 36180: Callers/Callees view) |
| *******************************************************************************/ |
| package org.eclipse.dltk.internal.ui.callhierarchy; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.dltk.core.IMember; |
| import org.eclipse.dltk.core.IMethod; |
| import org.eclipse.dltk.core.IModelElement; |
| import org.eclipse.dltk.core.ISourceRange; |
| import org.eclipse.dltk.core.ModelException; |
| import org.eclipse.dltk.internal.corext.callhierarchy.CallHierarchy; |
| import org.eclipse.dltk.internal.corext.callhierarchy.CallLocation; |
| import org.eclipse.dltk.internal.corext.callhierarchy.MethodWrapper; |
| import org.eclipse.dltk.internal.corext.util.Messages; |
| import org.eclipse.dltk.internal.ui.IDLTKStatusConstants; |
| import org.eclipse.dltk.internal.ui.actions.OpenActionUtil; |
| import org.eclipse.dltk.internal.ui.editor.EditorUtility; |
| import org.eclipse.dltk.ui.DLTKUIPlugin; |
| import org.eclipse.dltk.ui.util.ExceptionHandler; |
| import org.eclipse.jface.dialogs.ErrorDialog; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.util.OpenStrategy; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.texteditor.ITextEditor; |
| |
| public class CallHierarchyUI { |
| private static final int DEFAULT_MAX_CALL_DEPTH = 10; |
| private static final String PREF_MAX_CALL_DEPTH = "PREF_MAX_CALL_DEPTH"; //$NON-NLS-1$ |
| |
| private static CallHierarchyUI fgInstance; |
| |
| private CallHierarchyUI() { |
| // Do nothing |
| } |
| |
| public static CallHierarchyUI getDefault() { |
| if (fgInstance == null) { |
| fgInstance = new CallHierarchyUI(); |
| } |
| |
| return fgInstance; |
| } |
| |
| /** |
| * Returns the maximum tree level allowed |
| * |
| * @return int |
| */ |
| public int getMaxCallDepth() { |
| int maxCallDepth; |
| |
| IPreferenceStore settings = DLTKUIPlugin.getDefault().getPreferenceStore(); |
| maxCallDepth = settings.getInt(PREF_MAX_CALL_DEPTH); |
| if (maxCallDepth < 1 || maxCallDepth > 99) { |
| maxCallDepth = DEFAULT_MAX_CALL_DEPTH; |
| } |
| |
| return maxCallDepth; |
| } |
| |
| public void setMaxCallDepth(int maxCallDepth) { |
| IPreferenceStore settings = DLTKUIPlugin.getDefault().getPreferenceStore(); |
| settings.setValue(PREF_MAX_CALL_DEPTH, maxCallDepth); |
| } |
| |
| public static void jumpToMember(IModelElement element) { |
| if (element != null) { |
| try { |
| IEditorPart methodEditor = EditorUtility.openInEditor(element, true); |
| EditorUtility.revealInEditor(methodEditor, element); |
| } catch (ModelException e) { |
| DLTKUIPlugin.log(e); |
| } catch (PartInitException e) { |
| DLTKUIPlugin.log(e); |
| } |
| } |
| } |
| |
| public static void jumpToLocation(CallLocation callLocation) { |
| try { |
| IEditorPart methodEditor = EditorUtility.openInEditor(callLocation.getMember(), false); |
| |
| if (methodEditor instanceof ITextEditor) { |
| ITextEditor editor = (ITextEditor) methodEditor; |
| editor.selectAndReveal(callLocation.getStart(), (callLocation.getEnd() - callLocation.getStart())); |
| } |
| } catch (ModelException e) { |
| DLTKUIPlugin.log(e); |
| } catch (PartInitException e) { |
| DLTKUIPlugin.log(e); |
| } |
| } |
| |
| /** |
| * @return <code>true</code> iff no error occurred while trying to open the |
| * editor, <code>false</code> iff an error dialog was raised. |
| */ |
| public static boolean openInEditor(Object element, Shell shell, String title) { |
| CallLocation callLocation = CallHierarchy.getCallLocation(element); |
| |
| try { |
| IModelElement enclosingMember; |
| int selectionStart; |
| int selectionLength; |
| |
| if (callLocation != null) { |
| enclosingMember = callLocation.getMember(); |
| selectionStart = callLocation.getStart(); |
| selectionLength = callLocation.getEnd() - selectionStart; |
| } else if (element instanceof MethodWrapper) { |
| enclosingMember = ((MethodWrapper) element).getMember(); |
| ISourceRange selectionRange = null; |
| if (enclosingMember instanceof IMember) { |
| selectionRange = ((IMember) enclosingMember).getNameRange(); |
| } |
| if (selectionRange == null && enclosingMember instanceof IMember) |
| selectionRange = ((IMember) enclosingMember).getSourceRange(); |
| if (selectionRange == null) |
| return true; |
| selectionStart = selectionRange.getOffset(); |
| selectionLength = selectionRange.getLength(); |
| } else { |
| return true; |
| } |
| |
| boolean activateOnOpen = OpenStrategy.activateOnOpen(); |
| |
| IEditorPart methodEditor = EditorUtility.openInEditor(enclosingMember, activateOnOpen); |
| |
| if (methodEditor instanceof ITextEditor) { |
| ITextEditor editor = (ITextEditor) methodEditor; |
| editor.selectAndReveal(selectionStart, selectionLength); |
| } |
| return true; |
| } catch (ModelException e) { |
| DLTKUIPlugin.log(new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), IDLTKStatusConstants.INTERNAL_ERROR, |
| CallHierarchyMessages.CallHierarchyUI_open_in_editor_error_message, e)); |
| |
| ErrorDialog.openError(shell, title, CallHierarchyMessages.CallHierarchyUI_open_in_editor_error_message, |
| e.getStatus()); |
| return false; |
| } catch (PartInitException x) { |
| String name; |
| if (callLocation != null) |
| name = callLocation.getCalledMember().getElementName(); |
| else if (element instanceof MethodWrapper) |
| name = ((MethodWrapper) element).getName(); |
| else |
| name = ""; //$NON-NLS-1$ |
| MessageDialog.openError(shell, title, Messages.format( |
| CallHierarchyMessages.CallHierarchyUI_open_in_editor_error_messageArgs, name, x.getMessage())); |
| return false; |
| } |
| } |
| |
| public static IEditorPart isOpenInEditor(Object elem) { |
| IModelElement modelElement = null; |
| if (elem instanceof MethodWrapper) { |
| modelElement = ((MethodWrapper) elem).getMember(); |
| } else if (elem instanceof CallLocation) { |
| modelElement = ((CallLocation) elem).getCalledMember(); |
| } |
| if (modelElement != null) { |
| return EditorUtility.isOpenInEditor(modelElement); |
| } |
| return null; |
| } |
| |
| /** |
| * Converts the input to a possible input candidates |
| */ |
| public static IModelElement[] getCandidates(Object input) { |
| if (!(input instanceof IModelElement)) { |
| return null; |
| } |
| IModelElement elem = (IModelElement) input; |
| if (elem.getElementType() == IModelElement.METHOD) { |
| return new IModelElement[] { elem }; |
| } |
| return null; |
| } |
| |
| public static CallHierarchyViewPart open(IModelElement[] candidates, IWorkbenchWindow window, String partID) { |
| Assert.isTrue(candidates != null && candidates.length != 0); |
| |
| IModelElement input = null; |
| if (candidates.length > 1) { |
| String title = CallHierarchyMessages.CallHierarchyUI_selectionDialog_title; |
| String message = CallHierarchyMessages.CallHierarchyUI_selectionDialog_message; |
| input = OpenActionUtil.selectModelElement(candidates, window.getShell(), title, message); |
| } else { |
| input = candidates[0]; |
| } |
| if (input == null) |
| return null; |
| |
| return openInViewPart(window, input, partID); |
| } |
| |
| private static void openEditor(Object input, boolean activate) throws PartInitException, ModelException { |
| IEditorPart part = EditorUtility.openInEditor(input, activate); |
| if (input instanceof IModelElement) |
| EditorUtility.revealInEditor(part, (IModelElement) input); |
| } |
| |
| private static CallHierarchyViewPart openInViewPart(IWorkbenchWindow window, IModelElement input, String partID) { |
| IWorkbenchPage page = window.getActivePage(); |
| try { |
| CallHierarchyViewPart result = (CallHierarchyViewPart) page.showView(partID); |
| result.setMethod((IMethod) input); |
| openEditor(input, false); |
| return result; |
| } catch (CoreException e) { |
| ExceptionHandler.handle(e, window.getShell(), CallHierarchyMessages.CallHierarchyUI_error_open_view, |
| e.getMessage()); |
| } |
| return null; |
| } |
| |
| /** |
| * Converts an ISelection (containing MethodWrapper instances) to an ISelection |
| * with the MethodWrapper's replaced by their corresponding IMembers. If the |
| * selection contains elements which are not MethodWrapper instances or not |
| * already IMember instances they are discarded. |
| * |
| * @param selection The selection to convert. |
| * @return An ISelection containing IMember's in place of MethodWrapper |
| * instances. |
| */ |
| static ISelection convertSelection(ISelection selection) { |
| if (selection.isEmpty()) { |
| return selection; |
| } |
| |
| if (selection instanceof IStructuredSelection) { |
| IStructuredSelection structuredSelection = (IStructuredSelection) selection; |
| List modelElements = new ArrayList(); |
| for (Iterator iter = structuredSelection.iterator(); iter.hasNext();) { |
| Object element = iter.next(); |
| if (element instanceof MethodWrapper) { |
| IModelElement member = ((MethodWrapper) element).getMember(); |
| if (member != null) { |
| modelElements.add(member); |
| } |
| } else if (element instanceof IMember) { |
| modelElements.add(element); |
| } else if (element instanceof CallLocation) { |
| IModelElement member = ((CallLocation) element).getMember(); |
| modelElements.add(member); |
| } |
| } |
| return new StructuredSelection(modelElements); |
| } |
| return StructuredSelection.EMPTY; |
| } |
| } |