/*******************************************************************************
* Copyright (c) 2009 Vlad Dumitrescu 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
*
* Contributors:
* Vlad Dumitrescu
*******************************************************************************/
package org.erlide.ui.views;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.util.OpenStrategy;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;
import org.erlide.engine.ErlangEngine;
import org.erlide.engine.model.ErlModelException;
import org.erlide.engine.model.erlang.FunctionRef;
import org.erlide.engine.model.erlang.IErlFunction;
import org.erlide.engine.services.search.XrefService;
import org.erlide.ui.editors.util.EditorUtility;
import org.erlide.util.ErlLogger;
public class CallHierarchyView extends ViewPart {
Tree tree;
TreeViewer treeViewer;
Label lblRoot;
private final XrefService xrefService;
static class ViewerLabelProvider extends LabelProvider {
@Override
public Image getImage(final Object element) {
return super.getImage(element);
}
@Override
public String getText(final Object element) {
if (element instanceof IErlFunction) {
final IErlFunction ref = (IErlFunction) element;
final String n = ref.getModuleName();
return n + " : " + ref.toString();
}
return super.getText(element);
}
}
class TreeContentProvider implements ITreeContentProvider {
private Object input;
@Override
public void inputChanged(final Viewer viewer, final Object oldInput,
final Object newInput) {
input = newInput;
if (newInput instanceof IErlFunction) {
final IErlFunction fun = (IErlFunction) newInput;
lblRoot.setText(fun.getModuleName() + " : " + fun.getNameWithArity());
} else if (input instanceof String) {
lblRoot.setText((String) input);
}
}
@Override
public void dispose() {
}
@Override
public Object[] getElements(final Object inputElement) {
return getChildren(inputElement);
}
@Override
public Object[] getChildren(final Object parentElement) {
if (parentElement instanceof String) {
return new Object[0];
}
final IErlFunction parent = (IErlFunction) parentElement;
final FunctionRef ref = new FunctionRef(parent);
final FunctionRef[] children = xrefService.functionUse(ref);
if (children == null) {
return new Object[0];
}
if (parentElement == input && children.length == 0) {
// TODO ErlangXref should cache _all_ projects added to it
return new Object[] { "<no callers from project " + ErlangEngine
.getInstance()
.getModelUtilService().getProject(ErlangEngine.getInstance()
.getModelUtilService().getModule(parent))
.getName() + ">" };
}
final List<IErlFunction> result = new ArrayList<>();
for (final FunctionRef r : children) {
try {
final IErlFunction fun = ErlangEngine.getInstance().getModel()
.findFunction(r);
if (fun != null) {
result.add(fun);
}
} catch (final ErlModelException e) {
ErlLogger.error(e);
}
}
return result.toArray(new IErlFunction[result.size()]);
}
@Override
public Object getParent(final Object element) {
return null;
}
@Override
public boolean hasChildren(final Object element) {
return getChildren(element).length > 0;
}
}
public CallHierarchyView(final XrefService xrefService) {
this.xrefService = xrefService;
xrefService.start();
}
@Override
public void createPartControl(final Composite parent) {
{
final Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(2, false));
{
lblRoot = new Label(composite, SWT.NONE);
lblRoot.setLayoutData(
new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
lblRoot.setText("<no function>");
}
{
final ToolBar toolBar = new ToolBar(composite, SWT.FLAT);
toolBar.setLayoutData(
new GridData(SWT.RIGHT, SWT.CENTER, true, false, 1, 1));
{
final ToolItem tltmRefresh = new ToolItem(toolBar, SWT.NONE);
tltmRefresh.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
xrefService.update();
treeViewer.refresh();
}
});
tltmRefresh.setText("refresh");
}
}
{
treeViewer = new TreeViewer(composite, SWT.NONE);
treeViewer.setLabelProvider(new ViewerLabelProvider());
treeViewer.setContentProvider(new TreeContentProvider());
tree = treeViewer.getTree();
tree.addMouseListener(new MouseAdapter() {
@Override
public void mouseDoubleClick(final MouseEvent e) {
final TreeItem[] sel = tree.getSelection();
final IErlFunction el = (IErlFunction) sel[0].getData();
final boolean activateOnOpen = getSite() != null ? true
: OpenStrategy.activateOnOpen();
try {
EditorUtility.openElementInEditor(el, activateOnOpen);
} catch (final PartInitException e1) {
ErlLogger.error(e1);
}
}
});
tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true, 2, 1));
}
}
}
@Override
public void dispose() {
xrefService.stop();
super.dispose();
}
@Override
public void setFocus() {
tree.setFocus();
}
public void setRoot(final IErlFunction ref) {
if (ref == null) {
return;
}
treeViewer.setInput(ref);
// treeViewer.expandToLevel(2);
treeViewer.refresh();
}
public void setMessage(final String msg) {
if (msg == null) {
return;
}
treeViewer.setInput(msg);
treeViewer.refresh();
}
}