blob: 384b7b38a454e0221f9e3ea486771d69721bbc30 [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,
new String[] { 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;
}
}