/******************************************************************************* * Copyright (c) 2000, 2017 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 * *******************************************************************************/ package org.eclipse.dltk.internal.ui.callhierarchy; import java.util.ArrayList; import java.util.List; import org.eclipse.dltk.core.DLTKCore; import org.eclipse.dltk.core.DLTKLanguageManager; import org.eclipse.dltk.core.IDLTKLanguageToolkit; import org.eclipse.dltk.core.IMember; import org.eclipse.dltk.core.IMethod; import org.eclipse.dltk.core.IModelElement; import org.eclipse.dltk.core.search.IDLTKSearchScope; 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.actions.CCPActionGroup; import org.eclipse.dltk.internal.ui.actions.CompositeActionGroup; import org.eclipse.dltk.internal.ui.actions.refactoring.RefactorActionGroup; import org.eclipse.dltk.internal.ui.dnd.DelegatingDropAdapter; import org.eclipse.dltk.internal.ui.dnd.ResourceTransferDragAdapter; import org.eclipse.dltk.internal.ui.editor.EditorUtility; import org.eclipse.dltk.internal.ui.scriptview.SelectionTransferDragAdapter; import org.eclipse.dltk.ui.DLTKUIPlugin; import org.eclipse.dltk.ui.IContextMenuConstants; import org.eclipse.dltk.ui.ScriptElementLabels; import org.eclipse.dltk.ui.actions.OpenEditorActionGroup; import org.eclipse.dltk.ui.actions.OpenViewActionGroup; import org.eclipse.dltk.ui.viewsupport.SelectionProviderMediator; import org.eclipse.dltk.ui.viewsupport.StatusBarUpdater; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.util.LocalSelectionTransfer; import org.eclipse.jface.util.TransferDragSourceListener; import org.eclipse.jface.util.TransferDropTargetListener; 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.Viewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DropTarget; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ControlListener; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IMemento; import org.eclipse.ui.IPartListener2; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.IWorkbenchPartSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.actions.ActionContext; import org.eclipse.ui.actions.ActionGroup; import org.eclipse.ui.contexts.IContextActivation; import org.eclipse.ui.contexts.IContextService; import org.eclipse.ui.part.PageBook; import org.eclipse.ui.part.ResourceTransfer; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.texteditor.ITextEditor; /** * This is the main view for the callers plugin. It builds a tree of * callers/callees and allows the user to double click an entry to go to the * selected method. * */ public class CallHierarchyViewPart extends ViewPart implements ICallHierarchyViewPart, ISelectionChangedListener { private class CallHierarchySelectionProvider extends SelectionProviderMediator { public CallHierarchySelectionProvider(StructuredViewer[] viewers) { super(viewers, null); } @Override public ISelection getSelection() { ISelection selection = super.getSelection(); if (!selection.isEmpty()) { return CallHierarchyUI.convertSelection(selection); } return selection; } } private static final String DIALOGSTORE_VIEWORIENTATION = "CallHierarchyViewPart.orientation"; //$NON-NLS-1$ private static final String DIALOGSTORE_CALL_MODE = "CallHierarchyViewPart.call_mode"; //$NON-NLS-1$ /** * The key to be used is * <code>DIALOGSTORE_RATIO + fCurrentOrientation</code>. */ private static final String DIALOGSTORE_RATIO = "CallHierarchyViewPart.ratio"; //$NON-NLS-1$ static final int VIEW_ORIENTATION_VERTICAL = 0; static final int VIEW_ORIENTATION_HORIZONTAL = 1; static final int VIEW_ORIENTATION_SINGLE = 2; static final int VIEW_ORIENTATION_AUTOMATIC = 3; static final int CALL_MODE_CALLERS = 0; static final int CALL_MODE_CALLEES = 1; static final String GROUP_SEARCH_SCOPE = "MENU_SEARCH_SCOPE"; //$NON-NLS-1$ static final String ID_CALL_HIERARCHY = "org.eclipse.dltk.callhierarchy.view"; //$NON-NLS-1$ private static final String GROUP_FOCUS = "group.focus"; //$NON-NLS-1$ private static final int PAGE_EMPTY = 0; private static final int PAGE_VIEWER = 1; private Label fNoHierarchyShownLabel; private PageBook fPagebook; private IDialogSettings fDialogSettings; private int fCurrentOrientation; int fOrientation = CallHierarchyViewPart.VIEW_ORIENTATION_AUTOMATIC; private int fCurrentCallMode; private MethodWrapper fCalleeRoot; private MethodWrapper fCallerRoot; private IMemento fMemento; private IMethod fShownMethod; private CallHierarchySelectionProvider fSelectionProviderMediator; private List fMethodHistory; private LocationViewer fLocationViewer; private SashForm fHierarchyLocationSplitter; private Clipboard fClipboard; private SearchScopeActionGroup fSearchScopeActions; private ToggleOrientationAction[] fToggleOrientationActions; private ToggleCallModeAction[] fToggleCallModeActions; private CallHierarchyFiltersActionGroup fFiltersActionGroup; private HistoryDropDownAction fHistoryDropDownAction; private RefreshAction fRefreshAction; private OpenLocationAction fOpenLocationAction; private FocusOnSelectionAction fFocusOnSelectionAction; private CopyCallHierarchyAction fCopyAction; private CancelSearchAction fCancelSearchAction; private CompositeActionGroup fActionGroups; private CallHierarchyViewer fCallHierarchyViewer; private boolean fShowCallDetails; protected Composite fParent; private IPartListener2 fPartListener; private IContextActivation fContextActivation; public CallHierarchyViewPart() { super(); fDialogSettings = DLTKUIPlugin.getDefault().getDialogSettings(); fMethodHistory = new ArrayList(); } @Override public void setFocus() { fPagebook.setFocus(); } /** * Sets the history entries */ public void setHistoryEntries(IMethod[] elems) { fMethodHistory.clear(); for (int i = 0; i < elems.length; i++) { fMethodHistory.add(elems[i]); } updateHistoryEntries(); } /** * Gets all history entries. */ public IMethod[] getHistoryEntries() { if (fMethodHistory.size() > 0) { updateHistoryEntries(); } return (IMethod[]) fMethodHistory .toArray(new IMethod[fMethodHistory.size()]); } /** * Method setMethod. * * @param method */ public void setMethod(IMethod method) { if (method == null) { showPage(CallHierarchyViewPart.PAGE_EMPTY); return; } if (!method.equals(fShownMethod)) { addHistoryEntry(method); } this.fShownMethod = method; refresh(); } public void setInputElements(IMember[] members) { // IMember[] oldMembers= fInputElements; // fInputElements= members; if (members == null || members.length == 0) { showPage(PAGE_EMPTY); return; } if (members.length == 1 && members[0] instanceof IMethod) { this.fShownMethod = (IMethod) members[0]; } refresh(); } public IMethod getMethod() { return fShownMethod; } public MethodWrapper getCurrentMethodWrapper() { if (fCurrentCallMode == CallHierarchyViewPart.CALL_MODE_CALLERS) { return fCallerRoot; } else { return fCalleeRoot; } } /** * called from ToggleOrientationAction. * * @param orientation * VIEW_ORIENTATION_HORIZONTAL or VIEW_ORIENTATION_VERTICAL */ void setOrientation(int orientation) { if (fCurrentOrientation != orientation) { if ((fLocationViewer != null) && !fLocationViewer.getControl().isDisposed() && (fHierarchyLocationSplitter != null) && !fHierarchyLocationSplitter.isDisposed()) { if (orientation == CallHierarchyViewPart.VIEW_ORIENTATION_SINGLE) { setShowCallDetails(false); } else { if (fCurrentOrientation == CallHierarchyViewPart.VIEW_ORIENTATION_SINGLE) { setShowCallDetails(true); } boolean horizontal = orientation == CallHierarchyViewPart.VIEW_ORIENTATION_HORIZONTAL; fHierarchyLocationSplitter.setOrientation( horizontal ? SWT.HORIZONTAL : SWT.VERTICAL); } fHierarchyLocationSplitter.layout(); } updateCheckedState(); fCurrentOrientation = orientation; restoreSplitterRatio(); } } private void updateCheckedState() { for (int i = 0; i < fToggleOrientationActions.length; i++) { fToggleOrientationActions[i] .setChecked(fOrientation == fToggleOrientationActions[i] .getOrientation()); } } /** * called from ToggleCallModeAction. * * @param mode * CALL_MODE_CALLERS or CALL_MODE_CALLEES */ void setCallMode(int mode) { if (fCurrentCallMode != mode) { for (int i = 0; i < fToggleCallModeActions.length; i++) { fToggleCallModeActions[i].setChecked( mode == fToggleCallModeActions[i].getMode()); } fCurrentCallMode = mode; fDialogSettings.put(CallHierarchyViewPart.DIALOGSTORE_CALL_MODE, mode); updateView(); } } public IDLTKSearchScope getSearchScope() { return fSearchScopeActions.getSearchScope(); } public void setShowCallDetails(boolean show) { fShowCallDetails = show; showOrHideCallDetailsView(); } private void initDragAndDrop() { addDragAdapters(fCallHierarchyViewer); addDropAdapters(fCallHierarchyViewer); addDropAdapters(fLocationViewer); // dnd on empty hierarchy DropTarget dropTarget = new DropTarget(fPagebook, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK | DND.DROP_DEFAULT); dropTarget.setTransfer( new Transfer[] { LocalSelectionTransfer.getTransfer() }); dropTarget.addDropListener(new CallHierarchyTransferDropAdapter(this, fCallHierarchyViewer)); } private void addDropAdapters(StructuredViewer viewer) { Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getTransfer() }; int ops = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK | DND.DROP_DEFAULT; TransferDropTargetListener[] dropListeners = new TransferDropTargetListener[] { new CallHierarchyTransferDropAdapter(this, viewer) }; viewer.addDropSupport(ops, transfers, new DelegatingDropAdapter(dropListeners)); } private void addDragAdapters(StructuredViewer viewer) { int ops = DND.DROP_COPY | DND.DROP_LINK; Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getTransfer(), ResourceTransfer.getInstance() }; TransferDragSourceListener[] dragListeners = new TransferDragSourceListener[] { new SelectionTransferDragAdapter(viewer), new ResourceTransferDragAdapter(viewer) }; // viewer.addDragSupport(ops, transfers, new // DLTKViewerDragAdapter(viewer, dragListeners)); } @Override public void createPartControl(Composite parent) { fParent = parent; addResizeListener(parent); fPagebook = new PageBook(parent, SWT.NONE); // Page 1: Viewers createHierarchyLocationSplitter(fPagebook); createCallHierarchyViewer(fHierarchyLocationSplitter); createLocationViewer(fHierarchyLocationSplitter); // Page 2: Nothing selected fNoHierarchyShownLabel = new Label(fPagebook, SWT.TOP + SWT.LEFT + SWT.WRAP); fNoHierarchyShownLabel .setText(CallHierarchyMessages.CallHierarchyViewPart_empty); // initDragAndDrop(); showPage(CallHierarchyViewPart.PAGE_EMPTY); // PlatformUI.getWorkbench().getHelpSystem().setHelp(fPagebook, // IJavaHelpContextIds.CALL_HIERARCHY_VIEW); if (DLTKCore.DEBUG) { System.err.println("Add help support here..."); //$NON-NLS-1$ } fSelectionProviderMediator = new CallHierarchySelectionProvider( new StructuredViewer[] { fCallHierarchyViewer, fLocationViewer }); IStatusLineManager slManager = getViewSite().getActionBars() .getStatusLineManager(); fSelectionProviderMediator .addSelectionChangedListener(new StatusBarUpdater(slManager)); getSite().setSelectionProvider(fSelectionProviderMediator); fCallHierarchyViewer.initContextMenu( menu -> fillCallHierarchyViewerContextMenu(menu), getSite(), fSelectionProviderMediator); fClipboard = new Clipboard(parent.getDisplay()); makeActions(); fillViewMenu(); fillActionBars(); initOrientation(); initCallMode(); if (fMemento != null) { restoreState(fMemento); } restoreSplitterRatio(); addPartListener(); IContextService ctxService = getSite() .getService(IContextService.class); if (ctxService != null) { fContextActivation = ctxService .activateContext(DLTKUIPlugin.CONTEXT_VIEWS); } } private void restoreSplitterRatio() { String ratio = fDialogSettings.get( CallHierarchyViewPart.DIALOGSTORE_RATIO + fCurrentOrientation); if (ratio == null) { return; } int intRatio = Integer.parseInt(ratio); fHierarchyLocationSplitter .setWeights(new int[] { intRatio, 1000 - intRatio }); } private void saveSplitterRatio() { if (fHierarchyLocationSplitter != null && !fHierarchyLocationSplitter.isDisposed()) { int[] weigths = fHierarchyLocationSplitter.getWeights(); int ratio = (weigths[0] * 1000) / (weigths[0] + weigths[1]); String key = CallHierarchyViewPart.DIALOGSTORE_RATIO + fCurrentOrientation; fDialogSettings.put(key, ratio); } } private void addPartListener() { fPartListener = new IPartListener2() { @Override public void partActivated(IWorkbenchPartReference partRef) { } @Override public void partBroughtToTop(IWorkbenchPartReference partRef) { } @Override public void partClosed(IWorkbenchPartReference partRef) { if (CallHierarchyViewPart.ID_CALL_HIERARCHY .equals(partRef.getId())) { saveViewSettings(); } } @Override public void partDeactivated(IWorkbenchPartReference partRef) { if (CallHierarchyViewPart.ID_CALL_HIERARCHY .equals(partRef.getId())) { saveViewSettings(); } } @Override public void partOpened(IWorkbenchPartReference partRef) { } @Override public void partHidden(IWorkbenchPartReference partRef) { } @Override public void partVisible(IWorkbenchPartReference partRef) { } @Override public void partInputChanged(IWorkbenchPartReference partRef) { } }; getViewSite().getPage().addPartListener(fPartListener); } protected void saveViewSettings() { saveSplitterRatio(); fDialogSettings.put(CallHierarchyViewPart.DIALOGSTORE_VIEWORIENTATION, fOrientation); } private void addResizeListener(Composite parent) { parent.addControlListener(new ControlListener() { @Override public void controlMoved(ControlEvent e) { } @Override public void controlResized(ControlEvent e) { computeOrientation(); } }); } void computeOrientation() { saveSplitterRatio(); fDialogSettings.put(CallHierarchyViewPart.DIALOGSTORE_VIEWORIENTATION, fOrientation); if (fOrientation != CallHierarchyViewPart.VIEW_ORIENTATION_AUTOMATIC) { setOrientation(fOrientation); } else { if (fOrientation == CallHierarchyViewPart.VIEW_ORIENTATION_SINGLE) { return; } Point size = fParent.getSize(); if (size.x != 0 && size.y != 0) { if (size.x > size.y) { setOrientation( CallHierarchyViewPart.VIEW_ORIENTATION_HORIZONTAL); } else { setOrientation( CallHierarchyViewPart.VIEW_ORIENTATION_VERTICAL); } } } } private void showPage(int page) { if (page == CallHierarchyViewPart.PAGE_EMPTY) { fPagebook.showPage(fNoHierarchyShownLabel); } else { fPagebook.showPage(fHierarchyLocationSplitter); } } /** * Restores the type hierarchy settings from a memento. */ private void restoreState(IMemento memento) { fSearchScopeActions.restoreState(memento); } private void initCallMode() { int mode; try { mode = fDialogSettings .getInt(CallHierarchyViewPart.DIALOGSTORE_CALL_MODE); if ((mode < 0) || (mode > 1)) { mode = CallHierarchyViewPart.CALL_MODE_CALLERS; } } catch (NumberFormatException e) { mode = CallHierarchyViewPart.CALL_MODE_CALLERS; } // force the update fCurrentCallMode = -1; // will fill the main tool bar setCallMode(mode); } private void initOrientation() { try { fOrientation = fDialogSettings .getInt(CallHierarchyViewPart.DIALOGSTORE_VIEWORIENTATION); if ((fOrientation < 0) || (fOrientation > 3)) { fOrientation = CallHierarchyViewPart.VIEW_ORIENTATION_AUTOMATIC; } } catch (NumberFormatException e) { fOrientation = CallHierarchyViewPart.VIEW_ORIENTATION_AUTOMATIC; } // force the update fCurrentOrientation = -1; setOrientation(fOrientation); } private void fillViewMenu() { IActionBars actionBars = getViewSite().getActionBars(); IMenuManager viewMenu = actionBars.getMenuManager(); viewMenu.add(new Separator()); for (int i = 0; i < fToggleCallModeActions.length; i++) { viewMenu.add(fToggleCallModeActions[i]); } viewMenu.add(new Separator()); MenuManager layoutSubMenu = new MenuManager( CallHierarchyMessages.CallHierarchyViewPart_layout_menu); for (int i = 0; i < fToggleOrientationActions.length; i++) { layoutSubMenu.add(fToggleOrientationActions[i]); } viewMenu.add(layoutSubMenu); } /** * */ @Override public void dispose() { if (fContextActivation != null) { IContextService ctxService = getSite() .getService(IContextService.class); if (ctxService != null) { ctxService.deactivateContext(fContextActivation); } } if (fActionGroups != null) { fActionGroups.dispose(); } if (fClipboard != null) { fClipboard.dispose(); } if (fPartListener != null) { getViewSite().getPage().removePartListener(fPartListener); fPartListener = null; } super.dispose(); } /** * Goes to the selected entry, without updating the order of history * entries. */ public void gotoHistoryEntry(IMethod entry) { if (fMethodHistory.contains(entry)) { setMethod(entry); } } /* * (non-Javadoc) Method declared on IViewPart. */ @Override public void init(IViewSite site, IMemento memento) throws PartInitException { super.init(site, memento); fMemento = memento; } /** * */ public void refresh() { setCalleeRoot(null); setCallerRoot(null); updateView(); } @Override public void saveState(IMemento memento) { if (fPagebook == null) { // part has not been created if (fMemento != null) { // Keep the old state; memento.putMemento(fMemento); } return; } fSearchScopeActions.saveState(memento); } @Override public void selectionChanged(SelectionChangedEvent e) { if (e.getSelectionProvider() == fCallHierarchyViewer) { methodSelectionChanged(e.getSelection()); } } /** * @param selection */ private void methodSelectionChanged(ISelection selection) { if (selection instanceof IStructuredSelection && ((IStructuredSelection) selection).size() == 1) { Object selectedElement = ((IStructuredSelection) selection) .getFirstElement(); if (selectedElement instanceof MethodWrapper) { MethodWrapper methodWrapper = (MethodWrapper) selectedElement; revealElementInEditor(methodWrapper, fCallHierarchyViewer); updateLocationsView(methodWrapper); } else { updateLocationsView(null); } } else { updateLocationsView(null); } } private void revealElementInEditor(Object elem, Viewer originViewer) { // only allow revealing when the type hierarchy is the active pagae // no revealing after selection events due to model changes if (getSite().getPage().getActivePart() != this) { return; } if (fSelectionProviderMediator.getViewerInFocus() != originViewer) { return; } if (elem instanceof MethodWrapper) { CallLocation callLocation = CallHierarchy.getCallLocation(elem); if (callLocation != null) { IEditorPart editorPart = CallHierarchyUI .isOpenInEditor(callLocation); if (editorPart != null) { getSite().getPage().bringToTop(editorPart); if (editorPart instanceof ITextEditor) { ITextEditor editor = (ITextEditor) editorPart; editor.selectAndReveal(callLocation.getStart(), (callLocation.getEnd() - callLocation.getStart())); } } } else { IEditorPart editorPart = CallHierarchyUI.isOpenInEditor(elem); getSite().getPage().bringToTop(editorPart); EditorUtility.revealInEditor(editorPart, ((MethodWrapper) elem).getMember()); } } else if (elem instanceof IModelElement) { IEditorPart editorPart = EditorUtility.isOpenInEditor(elem); if (editorPart != null) { // getSite().getPage().removePartListener(fPartListener); getSite().getPage().bringToTop(editorPart); EditorUtility.revealInEditor(editorPart, (IModelElement) elem); // getSite().getPage().addPartListener(fPartListener); } } } /** * {@inheritDoc} */ @Override public <T> T getAdapter(Class<T> adapter) { // if (adapter == IContextProvider.class) { // return JavaUIHelp.getHelpContextProvider(this, // IJavaHelpContextIds.CALL_HIERARCHY_VIEW); // } if (DLTKCore.DEBUG) { System.err.println("Add help support here..."); //$NON-NLS-1$ } return super.getAdapter(adapter); } /** * Returns the current selection. */ protected ISelection getSelection() { StructuredViewer viewerInFocus = fSelectionProviderMediator .getViewerInFocus(); if (viewerInFocus != null) { return viewerInFocus.getSelection(); } return StructuredSelection.EMPTY; } protected void fillLocationViewerContextMenu(IMenuManager menu) { DLTKUIPlugin.createStandardGroups(menu); menu.appendToGroup(IContextMenuConstants.GROUP_SHOW, fOpenLocationAction); menu.appendToGroup(IContextMenuConstants.GROUP_SHOW, fRefreshAction); } protected void handleKeyEvent(KeyEvent event) { if (event.stateMask == 0) { if (event.keyCode == SWT.F5) { if ((fRefreshAction != null) && fRefreshAction.isEnabled()) { fRefreshAction.run(); return; } } } } private IActionBars getActionBars() { return getViewSite().getActionBars(); } private void setCalleeRoot(MethodWrapper calleeRoot) { this.fCalleeRoot = calleeRoot; } private MethodWrapper getCalleeRoot() { if (fCalleeRoot == null) { fCalleeRoot = CallHierarchy.getDefault() .getCalleeRoot(fShownMethod); } return fCalleeRoot; } private void setCallerRoot(MethodWrapper callerRoot) { this.fCallerRoot = callerRoot; } private MethodWrapper getCallerRoot() { if (fCallerRoot == null) { fCallerRoot = CallHierarchy.getDefault() .getCallerRoot(fShownMethod); } return fCallerRoot; } /** * Adds the entry if new. Inserted at the beginning of the history entries * list. */ private void addHistoryEntry(IModelElement entry) { if (fMethodHistory.contains(entry)) { fMethodHistory.remove(entry); } fMethodHistory.add(0, entry); fHistoryDropDownAction.setEnabled(!fMethodHistory.isEmpty()); } /** * @param parent */ private void createLocationViewer(Composite parent) { fLocationViewer = new LocationViewer(parent); fLocationViewer.getControl().addKeyListener(createKeyListener()); fLocationViewer.initContextMenu( menu -> fillLocationViewerContextMenu(menu), CallHierarchyViewPart.ID_CALL_HIERARCHY, getSite()); } private void createHierarchyLocationSplitter(Composite parent) { fHierarchyLocationSplitter = new SashForm(parent, SWT.NONE); fHierarchyLocationSplitter.addKeyListener(createKeyListener()); } private void createCallHierarchyViewer(Composite parent) { fCallHierarchyViewer = new CallHierarchyViewer(parent, this); fCallHierarchyViewer.addKeyListener(createKeyListener()); fCallHierarchyViewer.addSelectionChangedListener(this); } /** * @param menu */ protected void fillCallHierarchyViewerContextMenu(IMenuManager menu) { DLTKUIPlugin.createStandardGroups(menu); menu.appendToGroup(IContextMenuConstants.GROUP_SHOW, fRefreshAction); menu.appendToGroup(IContextMenuConstants.GROUP_SHOW, new Separator(CallHierarchyViewPart.GROUP_FOCUS)); if (fFocusOnSelectionAction.canActionBeAdded()) { menu.appendToGroup(CallHierarchyViewPart.GROUP_FOCUS, fFocusOnSelectionAction); } if (fCopyAction.canActionBeAdded()) { menu.appendToGroup(CallHierarchyViewPart.GROUP_FOCUS, fCopyAction); } fActionGroups.setContext(new ActionContext(getSelection())); fActionGroups.fillContextMenu(menu); fActionGroups.setContext(null); } private void fillActionBars() { IActionBars actionBars = getActionBars(); IToolBarManager toolBar = actionBars.getToolBarManager(); fActionGroups.fillActionBars(actionBars); toolBar.add(fCancelSearchAction); for (int i = 0; i < fToggleCallModeActions.length; i++) { toolBar.add(fToggleCallModeActions[i]); } toolBar.add(fHistoryDropDownAction); } private KeyListener createKeyListener() { KeyListener keyListener = new KeyAdapter() { @Override public void keyReleased(KeyEvent event) { handleKeyEvent(event); } }; return keyListener; } /** * */ private void makeActions() { fRefreshAction = new RefreshAction(this); fOpenLocationAction = new OpenLocationAction(this, getSite()); fLocationViewer.addOpenListener(event -> fOpenLocationAction.run()); fFocusOnSelectionAction = new FocusOnSelectionAction(this); fCopyAction = new CopyCallHierarchyAction(this, fClipboard, fCallHierarchyViewer); fSearchScopeActions = new SearchScopeActionGroup(this, fDialogSettings) { @Override protected IDLTKLanguageToolkit getLangaugeToolkit() { return getMethodLanguageToolkit(); } }; fFiltersActionGroup = new CallHierarchyFiltersActionGroup(this, fCallHierarchyViewer); fHistoryDropDownAction = new HistoryDropDownAction(this); fHistoryDropDownAction.setEnabled(false); fCancelSearchAction = new CancelSearchAction(this); setCancelEnabled(false); fToggleOrientationActions = new ToggleOrientationAction[] { new ToggleOrientationAction(this, CallHierarchyViewPart.VIEW_ORIENTATION_VERTICAL), new ToggleOrientationAction(this, CallHierarchyViewPart.VIEW_ORIENTATION_HORIZONTAL), new ToggleOrientationAction(this, CallHierarchyViewPart.VIEW_ORIENTATION_AUTOMATIC), new ToggleOrientationAction(this, CallHierarchyViewPart.VIEW_ORIENTATION_SINGLE) }; fToggleCallModeActions = new ToggleCallModeAction[] { new ToggleCallModeAction(this, CallHierarchyViewPart.CALL_MODE_CALLERS), new ToggleCallModeAction(this, CallHierarchyViewPart.CALL_MODE_CALLEES) }; fActionGroups = new CompositeActionGroup( new ActionGroup[] { new OpenEditorActionGroup(this), new OpenViewActionGroup(this), new CCPActionGroup(this), // new GenerateActionGroup(this), new RefactorActionGroup(this, null), // new DLTKSearchActionGroup(this), fSearchScopeActions, fFiltersActionGroup }); } protected IDLTKLanguageToolkit getMethodLanguageToolkit() { if (getMethod() != null) { return DLTKLanguageManager.getLanguageToolkit(getMethod()); } return null; } private void showOrHideCallDetailsView() { if (fShowCallDetails) { fHierarchyLocationSplitter.setMaximizedControl(null); } else { fHierarchyLocationSplitter .setMaximizedControl(fCallHierarchyViewer.getControl()); } } private void updateLocationsView(MethodWrapper methodWrapper) { if (methodWrapper != null && methodWrapper.getMethodCall().hasCallLocations()) { fLocationViewer .setInput(methodWrapper.getMethodCall().getCallLocations()); } else { fLocationViewer.clearViewer(); } } private void updateHistoryEntries() { for (int i = fMethodHistory.size() - 1; i >= 0; i--) { IMethod method = (IMethod) fMethodHistory.get(i); if (!method.exists()) { fMethodHistory.remove(i); } } fHistoryDropDownAction.setEnabled(!fMethodHistory.isEmpty()); } /** * Method updateView. */ private void updateView() { if ((fShownMethod != null)) { showPage(CallHierarchyViewPart.PAGE_VIEWER); CallHierarchy.getDefault().setSearchScope(getSearchScope()); String elementName = ScriptElementLabels.getDefault() .getElementLabel(fShownMethod, ScriptElementLabels.ALL_DEFAULT); String scopeDescription = fSearchScopeActions.getFullDescription(); String[] args = new String[] { elementName, scopeDescription }; // set input to null so that setSorter does not cause a refresh on // the old contents: fCallHierarchyViewer.setInput(null); if (fCurrentCallMode == CallHierarchyViewPart.CALL_MODE_CALLERS) { setContentDescription(Messages.format( CallHierarchyMessages.CallHierarchyViewPart_callsToMethod, args)); fCallHierarchyViewer.setComparator(new ViewerComparator()); // bug // 111423: // sort // caller // hierarchy // alphabetically fCallHierarchyViewer.setMethodWrapper(getCallerRoot()); } else { setContentDescription(Messages.format( CallHierarchyMessages.CallHierarchyViewPart_callsFromMethod, args)); fCallHierarchyViewer.setComparator(null); fCallHierarchyViewer.setMethodWrapper(getCalleeRoot()); } } } static CallHierarchyViewPart findAndShowCallersView( IWorkbenchPartSite site) { IWorkbenchPage workbenchPage = site.getPage(); CallHierarchyViewPart callersView = null; try { callersView = (CallHierarchyViewPart) workbenchPage .showView(CallHierarchyViewPart.ID_CALL_HIERARCHY); } catch (PartInitException e) { DLTKUIPlugin.log(e); } return callersView; } /** * Cancels the caller/callee search jobs that are currently running. */ void cancelJobs() { fCallHierarchyViewer.cancelJobs(); } /** * Sets the enablement state of the cancel button. * * @param enabled */ void setCancelEnabled(boolean enabled) { fCancelSearchAction.setEnabled(enabled); } }