package com.redhat.ceylon.eclipse.code.outline;
import static com.redhat.ceylon.eclipse.code.complete.CodeCompletions.getLabelDescriptionFor;
import static com.redhat.ceylon.eclipse.code.complete.CodeCompletions.getQualifiedDescriptionFor;
import static com.redhat.ceylon.eclipse.code.complete.CodeCompletions.getStyledDescriptionFor;
import static com.redhat.ceylon.eclipse.code.complete.CompletionUtil.overloads;
import static com.redhat.ceylon.eclipse.code.editor.Navigation.gotoDeclaration;
import static com.redhat.ceylon.eclipse.code.outline.CeylonLabelProvider.getImageForDeclaration;
import static com.redhat.ceylon.eclipse.code.outline.CeylonLabelProvider.getImageKeyForDeclaration;
import static com.redhat.ceylon.eclipse.code.outline.HierarchyMode.HIERARCHY;
import static com.redhat.ceylon.eclipse.code.outline.HierarchyMode.SUBTYPES;
import static com.redhat.ceylon.eclipse.code.outline.HierarchyMode.SUPERTYPES;
import static com.redhat.ceylon.eclipse.ui.CeylonPlugin.PLUGIN_ID;
import static com.redhat.ceylon.eclipse.ui.CeylonPlugin.imageRegistry;
import static com.redhat.ceylon.eclipse.ui.CeylonResources.CEYLON_HIER;
import static com.redhat.ceylon.eclipse.ui.CeylonResources.CEYLON_INHERITED;
import static com.redhat.ceylon.eclipse.ui.CeylonResources.CEYLON_SUB;
import static com.redhat.ceylon.eclipse.ui.CeylonResources.CEYLON_SUP;
import static com.redhat.ceylon.eclipse.ui.CeylonResources.CONFIG_LABELS;
import static com.redhat.ceylon.eclipse.ui.CeylonResources.GOTO;
import static com.redhat.ceylon.eclipse.ui.CeylonResources.HISTORY;
import static com.redhat.ceylon.eclipse.ui.CeylonResources.TYPE_MODE;
import static com.redhat.ceylon.eclipse.util.Nodes.findNode;
import static com.redhat.ceylon.eclipse.util.Nodes.getReferencedDeclaration;
import static com.redhat.ceylon.model.typechecker.model.ModelUtil.isAbstraction;
import static org.eclipse.ui.PlatformUI.getWorkbench;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.CompoundContributionItem;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.part.ViewPart;
import com.redhat.ceylon.compiler.typechecker.tree.Node;
import com.redhat.ceylon.eclipse.code.editor.CeylonEditor;
import com.redhat.ceylon.eclipse.code.open.OpenDeclarationInHierarchyAction;
import com.redhat.ceylon.eclipse.code.parse.CeylonParseController;
import com.redhat.ceylon.eclipse.code.preferences.CeylonFiltersPreferencePage;
import com.redhat.ceylon.eclipse.code.preferences.CeylonOutlinesPreferencePage;
import com.redhat.ceylon.eclipse.ui.CeylonPlugin;
import com.redhat.ceylon.eclipse.ui.CeylonResources;
import com.redhat.ceylon.eclipse.util.ModelProxy;
import com.redhat.ceylon.model.typechecker.model.Constructor;
import com.redhat.ceylon.model.typechecker.model.Declaration;
import com.redhat.ceylon.model.typechecker.model.DeclarationWithProximity;
import com.redhat.ceylon.model.typechecker.model.Referenceable;
import com.redhat.ceylon.model.typechecker.model.Scope;
import com.redhat.ceylon.model.typechecker.model.TypeDeclaration;
public class HierarchyView extends ViewPart {
private static final String EXCLUDE_JDK =
"excludeJDKInHierarchy";
private static final String EXCLUDE_ORACLE_JDK =
"excludeOracleJDKInHierarchy";
private static final Image GOTO_IMAGE =
imageRegistry().get(GOTO);
static final Image INHERITED_IMAGE =
imageRegistry().get(CEYLON_INHERITED);
private static final Image SORT_IMAGE =
imageRegistry().get(TYPE_MODE);
private CeylonHierarchyLabelProvider labelProvider;
private CeylonHierarchyContentProvider contentProvider;
private MembersLabelProvider membersLabelProvider;
private MembersContentProvider membersContentProvider;
private List<ModelProxy> history =
new ArrayList<ModelProxy>();
private void addToHistory(ModelProxy input) {
history.add(0, input);
if (history.size()>10) {
history.remove(10);
}
}
private TreeViewer treeViewer;
private TableViewer tableViewer;
private ModeAction hierarchyAction =
new ModeAction("Hierarchy",
"Switch to hierarchy mode",
CEYLON_HIER, HIERARCHY);
private ModeAction supertypesAction =
new ModeAction("Supertypes",
"Switch to supertypes mode",
CEYLON_SUP, SUPERTYPES);
private ModeAction subtypesAction =
new ModeAction("Subtypes",
"Switch to subtypes mode",
CEYLON_SUB, SUBTYPES);
private CLabel title;
private boolean showInherited;
private ViewForm viewForm;
private IPropertyChangeListener propertyChangeListener;
@Override
public void init(IViewSite site)
throws PartInitException {
super.init(site);
propertyChangeListener =
new IPropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent event) {
Font outlineFont = CeylonPlugin.getOutlineFont();
treeViewer.getControl().setFont(outlineFont);
tableViewer.getControl().setFont(outlineFont);
treeViewer.refresh();
tableViewer.refresh();
}
};
CeylonPlugin.getPreferences()
.addPropertyChangeListener(propertyChangeListener);
getWorkbench().getThemeManager()
.addPropertyChangeListener(propertyChangeListener);
}
@Override
public void dispose() {
super.dispose();
if (propertyChangeListener!=null) {
CeylonPlugin.getPreferences()
.removePropertyChangeListener(propertyChangeListener);
getWorkbench().getThemeManager()
.removePropertyChangeListener(propertyChangeListener);
propertyChangeListener = null;
}
}
void toggle() {
showInherited=!showInherited;
}
final class HistoryAction
extends Action implements IMenuCreator {
private Menu menu;
HistoryAction() {
super(null, AS_DROP_DOWN_MENU);
setMenuCreator(this);
setToolTipText("Previous Type Hierarchies");
this.setImageDescriptor(
imageRegistry().getDescriptor(
CeylonResources.HISTORY));
}
@Override
public void runWithEvent(Event event) {
if (history.size()>1) {
ModelProxy h = history.remove(1);
Declaration declaration = h.get();
ModelProxy input = new ModelProxy(declaration);
setTreeInput(input);
tableViewer.setInput(input);
history.add(0, h);
HierarchyView.this.setDescription(declaration);
title.setImage(getImageForDeclaration(declaration));
title.setText(getName(declaration));
}
}
@Override
public Menu getMenu(Menu parent) {
return null;
}
@Override
public Menu getMenu(Control parent) {
if (menu!=null) menu.dispose();
menu = new Menu(parent);
populateHistoryMenu(menu);
return menu;
}
@Override
public void dispose() {
if (menu!=null) menu.dispose();
}
}
private String getName(Declaration declaration) {
String name = declaration.getName();
return declaration.isClassOrInterfaceMember() ?
((Declaration) declaration.getContainer()).getName() + '.' + name
: name;
}
private void populateHistoryMenu(Menu menu) {
for (final ModelProxy h: history) {
final MenuItem item = new MenuItem(menu, SWT.PUSH);
final Declaration declaration = h.get();
if (declaration!=null) {
final Image image =
getImageForDeclaration(declaration);
item.setText(getName(declaration));
item.setImage(image);
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
ModelProxy input =
new ModelProxy(declaration);
setTreeInput(input);
tableViewer.setInput(input);
history.remove(h);
history.add(0, h);
setDescription(declaration);
title.setImage(item.getImage());
title.setText(item.getText());
}
});
}
}
new MenuItem(menu, SWT.SEPARATOR);
MenuItem clear = new MenuItem(menu, SWT.PUSH);
clear.setText("Clear History");
clear.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
history.clear();
}
});
}
private void populateHistoryMenu(MenuManager menu) {
for (final ModelProxy h: history) {
final Declaration declaration = h.get();
if (declaration!=null) {
ImageDescriptor image =
imageRegistry().getDescriptor(
getImageKeyForDeclaration(
declaration));
menu.add(new Action(getName(declaration), image) {
@Override
public void run() {
ModelProxy input =
new ModelProxy(declaration);
setTreeInput(input);
tableViewer.setInput(input);
history.remove(h);
history.add(0, h);
HierarchyView.this.setDescription(declaration);
title.setImage(getImageForDeclaration(declaration));
title.setText(getName(declaration));
}
});
}
}
menu.add(new Separator());
menu.add(new Action("Clear History") {
@Override
public void run() {
history.clear();
}
});
}
private final class MemberSorter extends ViewerSorter {
private boolean sortByType;
private int compare(Declaration x, Declaration y) {
String xname = x.getNameAsString();
String yname = y.getNameAsString();
if (xname==null && yname==null) {
return 0;
}
if (xname==null) {
return -1;
}
if (yname==null) {
return 1;
}
int result = xname.compareTo(yname);
if (result!=0) {
return result;
}
return x.getQualifiedNameString()
.compareTo(y.getQualifiedNameString());
}
@Override
public int compare(Viewer viewer, Object x, Object y) {
ModelProxy p = (ModelProxy) x;
ModelProxy q = (ModelProxy) y;
Declaration e = p.get();
Declaration f = q.get();
if (e==f) {
return 0;
}
else if (e==null) {
return 1;
}
else if (f==null) {
return -1;
}
if (sortByType) {
int result =
compare((Declaration) e.getContainer(),
(Declaration) f.getContainer());
if (result!=0) {
return result;
}
}
return compare(e, f);
}
public void toggle() {
sortByType = !sortByType;
}
}
private final class MembersContentProvider
implements IStructuredContentProvider {
@Override
public void inputChanged(Viewer viewer,
Object oldInput, Object newInput) {}
@Override
public void dispose() {}
@Override
public Object[] getElements(Object inputElement) {
if (inputElement instanceof ModelProxy) {
ModelProxy proxy = (ModelProxy) inputElement;
inputElement = proxy.get();
}
if (inputElement instanceof TypeDeclaration) {
TypeDeclaration declaration =
(TypeDeclaration) inputElement;
ArrayList<ModelProxy> list =
new ArrayList<ModelProxy>();
if (showInherited) {
Collection<DeclarationWithProximity> children =
declaration.getMatchingMemberDeclarations(
declaration.getUnit(), //TODO: is this correct??
declaration, "", 0, null)
.values();
for (DeclarationWithProximity dwp: children) {
Declaration d = dwp.getDeclaration();
if (!(d instanceof Constructor)) {
for (Declaration dec: overloads(d)) {
list.add(new ModelProxy(dec));
}
}
}
}
else {
for (Declaration dec: declaration.getMembers()) {
if (!(dec instanceof Constructor) &&
!isAbstraction(dec)) {
list.add(new ModelProxy(dec));
}
}
}
return list.toArray();
}
else {
return new Object[0];
}
}
}
class MembersLabelProvider extends StyledCellLabelProvider
implements DelegatingStyledCellLabelProvider.IStyledLabelProvider,
ILabelProvider {
@Override
public void addListener(ILabelProviderListener listener) {}
@Override
public void dispose() {}
@Override
public boolean isLabelProperty(Object element, String property) {
return false;
}
@Override
public void removeListener(ILabelProviderListener listener) {}
@Override
public Image getImage(Object element) {
if (element instanceof ModelProxy) {
ModelProxy proxy = (ModelProxy) element;
return getImageForDeclaration(proxy.get());
}
else {
return null;
}
}
@Override
public String getText(Object element) {
if (element instanceof ModelProxy) {
ModelProxy proxy = (ModelProxy) element;
final Declaration dec = proxy.get();
String desc = getLabelDescriptionFor(dec);
Scope container = dec.getContainer();
if (showInherited &&
container instanceof Declaration) {
Declaration dc = (Declaration) container;
desc += " \u2014 " + dc.getName();
}
return desc;
}
else {
return "";
}
}
@Override
public StyledString getStyledText(Object element) {
if (element instanceof ModelProxy) {
ModelProxy proxy = (ModelProxy) element;
Declaration dec = proxy.get();
return showInherited ?
getQualifiedDescriptionFor(dec) :
getStyledDescriptionFor(dec);
/*StyledString desc =
getStyledDescriptionFor(dec);
Scope container = dec.getContainer();
if (showInherited &&
container instanceof Declaration) {
desc.append(" \u2014 ", Highlights.PACKAGE_STYLER)
.append(((Declaration) container).getName(),
Highlights.TYPE_STYLER);
}
return desc;*/
}
else {
return new StyledString();
}
}
@Override
public void update(ViewerCell cell) {
Object element = cell.getElement();
if (element!=null) {
StyledString styledText =
getStyledText(element);
cell.setText(styledText.toString());
cell.setStyleRanges(styledText.getStyleRanges());
cell.setImage(getImage(element));
super.update(cell);
}
}
}
@Override
public void createPartControl(Composite parent) {
setContentDescription("");
final SashForm sash =
new SashForm(parent,
SWT.HORIZONTAL | SWT.SMOOTH);
sash.addControlListener(new ControlListener() {
boolean reentrant;
@Override
public void controlResized(ControlEvent e) {
if (reentrant) return;
reentrant = true;
try {
Rectangle bounds = sash.getBounds();
IActionBars actionBars = getViewSite()
.getActionBars();
IToolBarManager toolBarManager =
actionBars.getToolBarManager();
if (bounds.height>bounds.width) {
if (sash.getOrientation()!=SWT.VERTICAL) {
sash.setOrientation(SWT.VERTICAL);
createMainToolBar(toolBarManager);
toolBarManager.update(false);
viewForm.setTopLeft(null);
}
}
else {
if (sash.getOrientation()!=SWT.HORIZONTAL) {
sash.setOrientation(SWT.HORIZONTAL);
toolBarManager.removeAll();
toolBarManager.update(false);
ToolBarManager tbm =
new ToolBarManager(SWT.NONE);
createMainToolBar(tbm);
tbm.createControl(viewForm);
viewForm.setTopLeft(tbm.getControl());
}
}
actionBars.updateActionBars();
}
finally {
reentrant = false;
}
}
@Override
public void controlMoved(ControlEvent e) {}
});
createTreeMenu(createTree(sash));
createTableMenu(createTable(sash));
createViewMenu();
}
private void createViewMenu() {
IActionBars actionBars =
getViewSite().getActionBars();
IMenuManager menuManager =
actionBars.getMenuManager();
// menuManager.add(new ExpandAllAction());
// menuManager.add(new Separator());
menuManager.add(new OpenDeclarationInHierarchyAction(
"Open Declaration...", null));
menuManager.add(new HistoryMenu());
menuManager.add(new Separator());
final Action javaSDKAction =
new Action("Exclude Java SDK",
IAction.AS_CHECK_BOX) {
@Override
public void run() {
boolean checked = isChecked();
contentProvider.setExcludeJDK(checked);
CeylonPlugin.getPreferences()
.setValue(EXCLUDE_JDK, checked);
update();
}
};
javaSDKAction.setChecked(contentProvider.isExcludeJDK());
menuManager.add(javaSDKAction);
final Action oracleSDKAction =
new Action("Exclude Java SDK Internals",
IAction.AS_CHECK_BOX) {
@Override
public void run() {
boolean checked = isChecked();
contentProvider.setExcludeOracleJDK(checked);
CeylonPlugin.getPreferences()
.setValue(EXCLUDE_ORACLE_JDK, checked);
update();
}
};
oracleSDKAction.setChecked(
contentProvider.isExcludeOracleJDK());
menuManager.add(oracleSDKAction);
menuManager.add(new Separator());
Action configureAction =
new Action("Configure Labels...",
imageRegistry()
.getDescriptor(CONFIG_LABELS)) {
@Override
public void run() {
PreferencesUtil.createPreferenceDialogOn(
getSite().getShell(),
CeylonOutlinesPreferencePage.ID,
new String[] {
CeylonOutlinesPreferencePage.ID,
CeylonPlugin.COLORS_AND_FONTS_PAGE_ID,
CeylonFiltersPreferencePage.ID
},
null).open();
}
};
menuManager.add(configureAction);
}
private final class HistoryMenu
extends CompoundContributionItem {
@Override
protected IContributionItem[] getContributionItems() {
MenuManager historyMenu =
new MenuManager("History",
imageRegistry()
.getDescriptor(HISTORY),
"history");
populateHistoryMenu(historyMenu);
return new IContributionItem[] {historyMenu};
}
}
// private class ExpandAllAction extends Action {
//
// private ExpandAllAction() {
// super("Expand All");
// setToolTipText("Expand All");
//
// ImageDescriptor desc =
// imageRegistry.getDescriptor(EXPAND_ALL);
// setHoverImageDescriptor(desc);
// setImageDescriptor(desc);
// }
//
// @Override
// public void run() {
// if (treeViewer != null) {
// treeViewer.getTree().setRedraw(false);
// if (contentProvider.isVeryAbstractType()) {
// reveal();
// }
// else {
// treeViewer.expandAll();
// }
// treeViewer.getTree().setRedraw(true);
// }
// }
//
// }
private Tree createTree(SashForm sash) {
viewForm = new ViewForm(sash, SWT.FLAT);
final Tree tree = new Tree(viewForm, SWT.SINGLE);
GridData gd = new GridData(GridData.FILL_BOTH);
gd.heightHint = tree.getItemHeight() * 12;
tree.setLayoutData(gd);
viewForm.setContent(tree);
treeViewer = new TreeViewer(tree);
IPreferenceStore preferences = CeylonPlugin.getPreferences();
preferences.setDefault(EXCLUDE_ORACLE_JDK, true);
contentProvider =
new CeylonHierarchyContentProvider(getSite(),
"Hierarchy",
preferences.getBoolean(EXCLUDE_JDK),
preferences.getBoolean(EXCLUDE_ORACLE_JDK));
labelProvider =
new CeylonHierarchyLabelProvider() {
@Override
boolean isShowingRefinements() {
return contentProvider.isShowingRefinements();
}
};
treeViewer.setContentProvider(contentProvider);
treeViewer.setLabelProvider(labelProvider);
treeViewer.setAutoExpandLevel(1);
treeViewer.getTree().setFont(CeylonPlugin.getOutlineFont());
treeViewer.addSelectionChangedListener(
new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
TreeSelection selection =
(TreeSelection) event.getSelection();
CeylonHierarchyNode firstElement =
(CeylonHierarchyNode)
selection.getFirstElement();
if (firstElement!=null) {
Declaration declaration =
firstElement.getDeclaration();
if (declaration!=null) {
tableViewer.setInput(new ModelProxy(declaration));
title.setImage(getImageForDeclaration(declaration));
title.setText(declaration.getName());
}
}
}
});
treeViewer.addDoubleClickListener(
new IDoubleClickListener() {
@Override
public void doubleClick(DoubleClickEvent event) {
TreeSelection selection =
(TreeSelection)
event.getSelection();
Object firstElement =
selection.getFirstElement();
if (firstElement
instanceof CeylonHierarchyNode) {
CeylonHierarchyNode node =
(CeylonHierarchyNode) firstElement;
gotoDeclaration(node.getDeclaration());
}
}
});
return tree;
}
private Table createTable(SashForm sash) {
ViewForm viewForm = new ViewForm(sash, SWT.FLAT);
tableViewer = new TableViewer(viewForm,
SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
GridData gd = new GridData(GridData.FILL_BOTH);
// gd.heightHint = tableViewer.getTable().getItemHeight() * 12;
tableViewer.getTable().setLayoutData(gd);
viewForm.setContent(tableViewer.getTable());
title = new CLabel(viewForm, SWT.NONE);
ToolBar toolBar = new ToolBar(viewForm, SWT.NONE);
ToolItem toolItem = new ToolItem(toolBar, SWT.CHECK);
toolItem.setImage(INHERITED_IMAGE);
toolItem.setToolTipText("Show Inherited Members");
toolItem.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
toggle();
tableViewer.refresh();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {}
});
toolItem = new ToolItem(toolBar, SWT.CHECK);
toolItem.setImage(SORT_IMAGE);
toolItem.setToolTipText("Sort Members by Declaring Type");
final MemberSorter sorter = new MemberSorter();
tableViewer.setSorter(sorter);
toolItem.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
sorter.toggle();
tableViewer.refresh();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {}
});
viewForm.setTopRight(toolBar);
viewForm.setTopLeft(title);
viewForm.setTopCenter(title);
membersLabelProvider=new MembersLabelProvider();
membersContentProvider=new MembersContentProvider();
tableViewer.setLabelProvider(membersLabelProvider);
tableViewer.setContentProvider(membersContentProvider);
tableViewer.getTable().setFont(CeylonPlugin.getOutlineFont());
tableViewer.addDoubleClickListener(new IDoubleClickListener() {
@Override
public void doubleClick(DoubleClickEvent event) {
StructuredSelection selection =
(StructuredSelection) event.getSelection();
ModelProxy firstElement =
(ModelProxy) selection.getFirstElement();
gotoDeclaration(firstElement.get());
}
});
return tableViewer.getTable();
}
private void createMainToolBar(IToolBarManager toolBarManager) {
toolBarManager.add(hierarchyAction);
toolBarManager.add(supertypesAction);
toolBarManager.add(subtypesAction);
updateActions(contentProvider.getMode());
// toolBarManager.add(new ExpandAllAction());
toolBarManager.add(new HistoryAction());
}
private void createTreeMenu(final Tree tree) {
Menu menu = new Menu(tree);
tree.setMenu(menu);
MenuItem item = new MenuItem(menu, SWT.PUSH);
item.setText("Focus on Selected Type");
// item.setImage(getTitleImage());
item.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
StructuredSelection selection =
(StructuredSelection)
treeViewer.getSelection();
Object firstElement =
selection.getFirstElement();
if (firstElement
instanceof CeylonHierarchyNode) {
CeylonHierarchyNode node =
(CeylonHierarchyNode)
firstElement;
Declaration declaration =
node.getDeclaration();
if (declaration.isClassOrInterfaceMember()) {
declaration =
(Declaration)
declaration.getContainer();
}
ModelProxy input =
new ModelProxy(declaration);
setTreeInput(input);
tableViewer.setInput(input);
addToHistory(input);
setDescription(declaration);
title.setImage(getImageForDeclaration(declaration));
title.setText(declaration.getName());
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {}
});
item = new MenuItem(menu, SWT.PUSH);
item.setText("Focus on Selection");
item.setImage(getTitleImage());
item.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
TreeSelection selection =
(TreeSelection)
treeViewer.getSelection();
Object firstElement =
selection.getFirstElement();
if (firstElement
instanceof CeylonHierarchyNode) {
CeylonHierarchyNode node =
(CeylonHierarchyNode)
firstElement;
Declaration declaration =
node.getDeclaration();
ModelProxy input =
new ModelProxy(declaration);
setTreeInput(input);
addToHistory(input);
setDescription(declaration);
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {}
});
item = new MenuItem(menu, SWT.PUSH);
item.setText("Go to Selection");
item.setImage(GOTO_IMAGE);
item.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
TreeSelection selection =
(TreeSelection)
treeViewer.getSelection();
Object firstElement =
selection.getFirstElement();
if (firstElement
instanceof CeylonHierarchyNode) {
CeylonHierarchyNode node =
(CeylonHierarchyNode)
firstElement;
gotoDeclaration(node.getDeclaration());
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {}
});
}
private void createTableMenu(final Table table) {
Menu menu = new Menu(table);
table.setMenu(menu);
MenuItem item = new MenuItem(menu, SWT.PUSH);
item.setText("Focus on Selection");
item.setImage(getTitleImage());
item.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
StructuredSelection selection =
(StructuredSelection)
tableViewer.getSelection();
Object firstElement =
selection.getFirstElement();
if (firstElement instanceof ModelProxy) {
ModelProxy input =
(ModelProxy) firstElement;
setTreeInput(input);
tableViewer.setInput(input);
addToHistory(input);
Declaration declaration = input.get();
setDescription(declaration);
title.setImage(getImageForDeclaration(declaration));
title.setText(declaration.getName());
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {}
});
item = new MenuItem(menu, SWT.PUSH);
item.setText("Go to Selection");
item.setImage(GOTO_IMAGE);
item.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
StructuredSelection selection =
(StructuredSelection)
tableViewer.getSelection();
Object firstElement =
selection.getFirstElement();
if (firstElement instanceof ModelProxy) {
ModelProxy proxy =
(ModelProxy) firstElement;
gotoDeclaration(proxy.get());
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {}
});
}
private void updateActions(HierarchyMode mode) {
hierarchyAction.setChecked(mode==HIERARCHY);
supertypesAction.setChecked(mode==SUPERTYPES);
subtypesAction.setChecked(mode==SUBTYPES);
}
private void update() {
ModelProxy input =
(ModelProxy) tableViewer.getInput();
if (input!=null) {
setDescription(input.get());
}
treeViewer.getControl().setRedraw(false);
// refresh viewer to re-filter
treeViewer.refresh();
reveal();
// selectFirstMatch(); //TODO select the main declaration instead!
treeViewer.getControl().setRedraw(true);
}
private void reveal() {
if (contentProvider.isEmpty()) return;
int depth;
if (contentProvider.getMode()==HIERARCHY) {
depth = contentProvider.getDepthInHierarchy();
}
else {
depth = 1;
}
if (contentProvider.isVeryAbstractType()) {
depth+=1;
}
else {
depth+=2;
}
treeViewer.expandToLevel(depth);
}
@Override
public void setFocus() {}
public void focusOnSelection(CeylonEditor editor) {
CeylonParseController parseController =
editor.getParseController();
Node node =
findNode(parseController.getLastCompilationUnit(),
parseController.getTokens(),
editor.getSelection());
Referenceable dec = getReferencedDeclaration(node);
if (dec instanceof Declaration) {
focusOn((Declaration) dec);
}
}
public void focusOn(Declaration declaration) {
if (declaration!=null) {
ModelProxy input = new ModelProxy(declaration);
setTreeInput(input);
tableViewer.setInput(input);
addToHistory(input);
setDescription(declaration);
title.setImage(getImageForDeclaration(declaration));
title.setText(declaration.getName());
}
}
private void setTreeInput(ModelProxy input) {
treeViewer.getTree().setRedraw(false);
treeViewer.setInput(input);
reveal();
treeViewer.getTree().setRedraw(true);
}
private void setDescription(Declaration dec) {
// setContentDescription("Displaying " +
// contentProvider.getMode().name().toLowerCase() +
// " of '" + dec.getName() + "'");
setContentDescription(contentProvider.getDescription());
}
public static HierarchyView showHierarchyView()
throws PartInitException {
IWorkbenchPage page = getWorkbench()
.getActiveWorkbenchWindow()
.getActivePage();
return (HierarchyView) page.showView(PLUGIN_ID +
".view.HierarchyView");
}
/*private class MembersAction extends Action {
MembersAction() {
super("Show Inherited Members");
setToolTipText("Show inherited members");
setImageDescriptor(CeylonPlugin.getInstance()
.getImageRegistry()
.getDescriptor(CEYLON_INHERITED));
}
@Override
public void run() {
membersContentProvider.toggle();
update();
setChecked(!isChecked());
}
}*/
private class ModeAction extends Action {
HierarchyMode mode;
ModeAction(String label, String tooltip,
String imageKey, HierarchyMode mode) {
super(label);
setToolTipText(tooltip);
setImageDescriptor(CeylonPlugin.imageRegistry()
.getDescriptor(imageKey));
this.mode = mode;
}
@Override
public void run() {
contentProvider.setMode(mode);
update();
updateActions(mode);
}
}
}