blob: 1fc7144b1e56121aab0037a18124c8e3fbce3635 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}