/* * Copyright (c) 2012, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.tools.ui.internal.typehierarchy; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.dart.engine.element.ClassElement; import com.google.dart.tools.core.DartCoreDebug; import com.google.dart.tools.ui.DartToolsPlugin; import com.google.dart.tools.ui.actions.OpenAction_NEW; import com.google.dart.tools.ui.actions.OpenAction_OLD; import com.google.dart.tools.ui.actions.OpenViewActionGroup_OLD; import com.google.dart.tools.ui.internal.text.editor.CompositeActionGroup; import com.google.dart.tools.ui.internal.typehierarchy.TypeHierarchyContentProvider_NEW.TypeItem; import org.dartlang.analysis.server.protocol.Element; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.custom.ViewForm; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Tree; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IMemento; import org.eclipse.ui.IViewSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.actions.ActionContext; import org.eclipse.ui.actions.ActionGroup; import org.eclipse.ui.part.PageBook; import org.eclipse.ui.part.ViewPart; /** * View showing the super types/sub types of its input. */ public class TypeHierarchyViewPart extends ViewPart { private static final String TAG_RATIO = "ratio"; //$NON-NLS-1$ private Object inputType; private IMemento fMemento; private PageBook fPagebook; private Control typeViewerControl; private SashForm fTypeMethodsSplitter; private Label fNoHierarchyShownLabel; private ViewForm fTypeViewerViewForm; private ViewForm fMethodViewerViewForm; private TreeViewer typesViewer; private MethodsViewer methodsViewer; private OpenAction_OLD fOpenAction_OLD; private Menu contextMenu; private CompositeActionGroup actionGroups; public TypeHierarchyViewPart() { } @Override public void createPartControl(Composite container) { fPagebook = new PageBook(container, SWT.NONE); // page 1 of page book (no hierarchy label) { fNoHierarchyShownLabel = new Label(fPagebook, SWT.TOP | SWT.LEFT | SWT.WRAP); fNoHierarchyShownLabel.setText(TypeHierarchyMessages.TypeHierarchyViewPart_empty); } // page 2 of page book (viewers) if (DartCoreDebug.ENABLE_ANALYSIS_SERVER) { typeViewerControl = createTypeViewerControl(fPagebook); fPagebook.showPage(fNoHierarchyShownLabel); } else { { fTypeMethodsSplitter = new SashForm(fPagebook, SWT.VERTICAL); fTypeMethodsSplitter.setVisible(false); fTypeViewerViewForm = new ViewForm(fTypeMethodsSplitter, SWT.NONE); Control typeViewerControl = createTypeViewerControl(fTypeViewerViewForm); fTypeViewerViewForm.setContent(typeViewerControl); fMethodViewerViewForm = new ViewForm(fTypeMethodsSplitter, SWT.NONE); fTypeMethodsSplitter.setWeights(new int[] {65, 35}); Control methodViewerPart = createMethodViewerControl(fMethodViewerViewForm); fMethodViewerViewForm.setContent(methodViewerPart); } fPagebook.showPage(fNoHierarchyShownLabel); // fill the tool bar IToolBarManager toolbarManager = getViewSite().getActionBars().getToolBarManager(); methodsViewer.contributeToToolBar(toolbarManager); toolbarManager.update(true); if (fMemento != null) { restoreState(fMemento); } if (!DartCoreDebug.ENABLE_ANALYSIS_SERVER) { fOpenAction_OLD = new OpenAction_OLD(getSite()); } } } @Override public void dispose() { super.dispose(); } @Override public void init(IViewSite site, IMemento memento) throws PartInitException { super.init(site, memento); fMemento = memento; } @Override public void saveState(IMemento memento) { if (DartCoreDebug.ENABLE_ANALYSIS_SERVER) { } else { // part is not created yet, keep old state if (fPagebook == null) { if (fMemento != null) { memento.putMemento(fMemento); } return; } // save state { int weigths[] = fTypeMethodsSplitter.getWeights(); int ratio = (weigths[0] * 1000) / (weigths[0] + weigths[1]); memento.putInteger(TAG_RATIO, ratio); } methodsViewer.saveState(memento); } } @Override public void setFocus() { fPagebook.setFocus(); } /** * Sets the input to a new element. */ public void setInputElement(Object element) { if (DartCoreDebug.ENABLE_ANALYSIS_SERVER) { // show hierarchy inputType = element; fPagebook.showPage(typeViewerControl); typesViewer.setInput(inputType); typesViewer.expandToLevel(inputType, 1); typesViewer.setSelection(new StructuredSelection(inputType)); } else { // may be not a Type if (!(element instanceof ClassElement)) { typesViewer.setInput(null); methodsViewer.setInputType(null); return; } // show hierarchy inputType = element; fPagebook.showPage(fTypeMethodsSplitter); typesViewer.setInput(new Object[] {inputType}); typesViewer.expandToLevel(inputType, 1); typesViewer.setSelection(new StructuredSelection(inputType)); } } private void contextMenuAboutToShow(IMenuManager menu) { DartToolsPlugin.createStandardGroups(menu); ISelection selection = typesViewer.getSelection(); actionGroups.setContext(new ActionContext(selection)); actionGroups.fillContextMenu(menu); } private Control createMethodViewerControl(Composite parent) { methodsViewer = new MethodsViewer(parent); ((StructuredViewer) methodsViewer).addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { fOpenAction_OLD.run((IStructuredSelection) selection); } } }); return ((Viewer) methodsViewer).getControl(); } private Control createTypeViewerControl(Composite parent) { typesViewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); Tree tree = typesViewer.getTree(); if (DartCoreDebug.ENABLE_ANALYSIS_SERVER) { TypeHierarchyContentProvider_NEW contentProvider = new TypeHierarchyContentProvider_NEW(); typesViewer.setContentProvider(contentProvider); Predicate<Object> predicate = contentProvider.getLightPredicate(); typesViewer.setLabelProvider(new TypeHierarchyLabelProvider_NEW(predicate)); } else { typesViewer.setContentProvider(new TypeHierarchyContentProvider_OLD()); typesViewer.setLabelProvider(new TypeHierarchyLabelProvider_OLD(Predicates.alwaysFalse())); } // register "viewer" as selection provide for this view IViewSite site = getViewSite(); site.setSelectionProvider(typesViewer); // configure actions if (DartCoreDebug.ENABLE_ANALYSIS_SERVER) { actionGroups = new CompositeActionGroup(new ActionGroup[] {}); } else { actionGroups = new CompositeActionGroup(new ActionGroup[] {new OpenViewActionGroup_OLD(site)}); } // configure actions { IActionBars actionBars = site.getActionBars(); actionGroups.fillActionBars(actionBars); } // prepare context menu MenuManager manager = new MenuManager(); manager.setRemoveAllWhenShown(true); manager.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(IMenuManager m) { contextMenuAboutToShow(m); } }); contextMenu = manager.createContextMenu(tree); tree.setMenu(contextMenu); if (!DartCoreDebug.ENABLE_ANALYSIS_SERVER) { typesViewer.addPostSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { IStructuredSelection structuredSelection = (IStructuredSelection) selection; Object selectedElement = structuredSelection.getFirstElement(); methodsViewer.setInputType(selectedElement); } } }); } typesViewer.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { IStructuredSelection structuredSelection = (IStructuredSelection) selection; if (DartCoreDebug.ENABLE_ANALYSIS_SERVER) { if (structuredSelection.size() == 1) { Object object = structuredSelection.getFirstElement(); // prepare Element to open Element element = null; if (object instanceof TypeItem) { TypeItem typeItem = (TypeItem) object; element = typeItem.getElementToOpen(); } else if (object instanceof Element) { element = (Element) object; } // open Element OpenAction_NEW.open(element); } } else { fOpenAction_OLD.run((IStructuredSelection) selection); } } } }); return tree; } /** * Restores the type hierarchy settings from a memento. */ private void restoreState(IMemento memento) { if (!DartCoreDebug.ENABLE_ANALYSIS_SERVER) { { Integer ratio = memento.getInteger(TAG_RATIO); if (ratio != null) { fTypeMethodsSplitter.setWeights(new int[] {ratio.intValue(), 1000 - ratio.intValue()}); } } methodsViewer.restoreState(memento); } } }