Java tutorial
/******************************************************************************* * Copyright (c) 2004 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 * * Contributors: * IBM Corporation - initial API and implementation * Helen Hawkins - iniital version *******************************************************************************/ package org.eclipse.contribution.xref.ui.views; import java.util.Iterator; import java.util.List; import org.eclipse.contribution.xref.core.IXReferenceAdapter; import org.eclipse.contribution.xref.core.XReferenceProviderManager; import org.eclipse.contribution.xref.internal.ui.actions.CollapseAllAction; import org.eclipse.contribution.xref.internal.ui.actions.CopyAction; import org.eclipse.contribution.xref.internal.ui.actions.DoubleClickAction; import org.eclipse.contribution.xref.internal.ui.actions.SelectAllAction; import org.eclipse.contribution.xref.internal.ui.actions.ToggleLinkingAction; import org.eclipse.contribution.xref.internal.ui.actions.ToggleShowXRefsForFileAction; import org.eclipse.contribution.xref.internal.ui.actions.XReferenceCustomFilterAction; import org.eclipse.contribution.xref.internal.ui.help.IXRefHelpContextIds; import org.eclipse.contribution.xref.internal.ui.help.XRefUIHelp; import org.eclipse.contribution.xref.internal.ui.providers.XReferenceContentProvider; import org.eclipse.contribution.xref.internal.ui.providers.XReferenceLabelProvider; import org.eclipse.contribution.xref.internal.ui.utils.XRefUIUtils; import org.eclipse.contribution.xref.ui.XReferenceUIPlugin; import org.eclipse.help.IContextProvider; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jface.action.Action; 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.preference.IPreferenceStore; import org.eclipse.jface.viewers.AbstractTreeViewer; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Menu; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IPartListener; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.texteditor.AbstractTextEditor; import org.eclipse.ui.views.contentoutline.ContentOutline; /** * This class represents the Cross Reference View */ public class XReferenceView extends ViewPart implements ISelectionListener, IPartListener { public static final String ID = "org.eclipse.contribution.xref.ui.views.XReferenceView"; //$NON-NLS-1$ public static final String LINK_ID = ID + ".link"; //$NON-NLS-1$ public static final String XREFS_FOR_FILE_ID = ID + ".xrefsForFile"; //$NON-NLS-1$ private Action doubleClickAction; private Action collapseAllAction; private Action toggleLinkingAction; private Action toggleShowXRefsForFileAction; private Action xRefCustomFilterAction; private Action copyAction; private Action selectAllAction; private boolean linkingEnabled = true; // following selection? private boolean showXRefsForFileEnabled = false; private boolean changeDrivenByBuild = false; private List /* IXReferenceAdapter */ lastXRefAdapterList; private List /* IXReferenceAdapter */ lastLinkedXRefAdapterList; private ISelection lastSelection, lastLinkedSelection; private IWorkbenchPart lastWorkbenchPart, lastLinkedWorkbenchPart; private IJavaElement lastJavaElement, lastLinkedJavaElement; private TreeViewer viewer; private XReferenceContentProvider contentProvider; private Clipboard fClipboard; public XReferenceView() { XReferenceUIPlugin.xrefView = this; } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) */ public void createPartControl(Composite parent) { viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); contentProvider = new XReferenceContentProvider(); viewer.setContentProvider(contentProvider); viewer.setLabelProvider(new XReferenceLabelProvider()); viewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS); fClipboard = new Clipboard(viewer.getTree().getDisplay()); restorePersistedSettings(); makeActions(); hookDoubleClickAction(); contributeToActionBars(); IWorkbenchWindow window = XRefUIUtils.getActiveWorkbenchWindow(); if (window != null) { window.getSelectionService().addPostSelectionListener(this); } getSite().setSelectionProvider(viewer); // context menu MenuManager mgr = new MenuManager(); mgr.add(copyAction); mgr.add(selectAllAction); // add the standard extension group mgr.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); Menu menu = mgr.createContextMenu(viewer.getControl()); viewer.getControl().setMenu(menu); getSite().registerContextMenu(mgr, viewer); } /** * Passing the focus request to the viewer's control. */ public void setFocus() { viewer.getControl().setFocus(); } /* * (non-Javadoc) * * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, * org.eclipse.jface.viewers.ISelection) */ public void selectionChanged(IWorkbenchPart part, ISelection selection) { // enhancement 95724 - adding filter to xref view XReferenceProviderManager.getManager().setIsInplace(false); addListenersToOpenEditors(); if (!(part instanceof AbstractTextEditor) && !(part instanceof ContentOutline)) { // only want to respond to changes in selection // in editors and outline view return; } // if linking is enabled we want to work with the current // selection in the workbench, otherwise we want to work // with the last linked selection (since we're not linked with // the editor, we really don't care what was selected and are // really responding to changes due to a build) List xraList = null; lastJavaElement = XRefUIUtils.getSelectedJavaElement(part, selection); if (linkingEnabled) { // calculate the xrefs for the current selection if (showXRefsForFileEnabled) { xraList = XRefUIUtils.getXRefAdapterListForJavaElement(lastJavaElement, true); } else { xraList = XRefUIUtils.getXRefAdapterListForJavaElement(lastJavaElement, false); } if (xraList == null || xraList.isEmpty() || !lastJavaElement.exists()) { // if there are compilation errors then we want to clear // the view (in this case, xraList is empty or null) clearView(); } else if (lastXRefAdapterList == null || lastXRefAdapterList.isEmpty()) { //if this is the first selection (i.e. lastXRefAdapterList == null) // then just set the input to be the just calculated xrefs // OR // if compilatin errors occurred last time (lastXRefAdapterList is empty) // and this time they're fixed then just set the input to be the xrefs viewer.setInput(xraList); XRefUIUtils.setSelection(part, selection, viewer); } else { if (!sameXRefAdapter(lastXRefAdapterList, xraList)) { // if now selecting a new element in the editor then // need to update the view to contain this viewer.setInput(xraList); XRefUIUtils.setSelection(part, selection, viewer); } else if (changeDrivenByBuild) { // if the change has been driven by a build then // need to update view since xrefs may have changed viewer.setInput(xraList); XRefUIUtils.setSelection(part, selection, viewer); } else { XRefUIUtils.setSelection(part, selection, viewer); } } // record what was last selected and last calculated lastWorkbenchPart = part; lastSelection = selection; lastXRefAdapterList = xraList; lastLinkedSelection = selection; lastLinkedWorkbenchPart = part; lastLinkedXRefAdapterList = xraList; lastLinkedJavaElement = lastJavaElement; } else { // calculate the xrefs for the last linked selection - these may have // changed due to a build if (showXRefsForFileEnabled) { xraList = XRefUIUtils.getXRefAdapterListForJavaElement(lastLinkedJavaElement, true); } else { xraList = XRefUIUtils.getXRefAdapterListForJavaElement(lastLinkedJavaElement, false); } if (xraList == null || xraList.isEmpty() || !lastLinkedJavaElement.exists()) { // if there are compilation errors then we want to clear // the view (in this case, xraList is empty or null) clearView(); } else if (lastXRefAdapterList == null || lastXRefAdapterList.isEmpty()) { // if compilation errors occurred last time (lastXRefAdapterList is empty) // and this time they're fixed then we need to update the xref view. If // we've selected the same thing viewer.setInput(xraList); XRefUIUtils.setSelection(lastLinkedWorkbenchPart, lastLinkedSelection, viewer); } else if (sameXRefAdapter(lastLinkedXRefAdapterList, xraList) && changeDrivenByBuild) { // if anything has changed about the contents, then need to refresh // (this will come from a build) viewer.setInput(xraList); XRefUIUtils.setSelection(lastLinkedWorkbenchPart, lastLinkedSelection, viewer); } // record what was last selected and last calculated lastWorkbenchPart = part; lastSelection = selection; lastXRefAdapterList = xraList; } } private boolean sameXRefAdapter(List previousXRefAdapterList, List currentXRefAdapterList) { boolean sameXRefAdapter = true; for (Iterator iter = currentXRefAdapterList.iterator(); iter.hasNext();) { Object o = iter.next(); boolean foundMatch = false; if (o instanceof IXReferenceAdapter) { IXReferenceAdapter currentXra = (IXReferenceAdapter) o; for (Iterator i2 = previousXRefAdapterList.iterator(); i2.hasNext();) { Object o2 = i2.next(); if (o2 instanceof IXReferenceAdapter) { IXReferenceAdapter lastXra = (IXReferenceAdapter) o2; if (currentXra.getReferenceSource().equals(lastXra.getReferenceSource())) { foundMatch = true; } } } } if (!foundMatch) { sameXRefAdapter = false; } } return sameXRefAdapter; } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbenchPart#dispose() */ public void dispose() { super.dispose(); if (fClipboard != null) { fClipboard.dispose(); fClipboard = null; } IWorkbenchWindow window = XRefUIUtils.getActiveWorkbenchWindow(); if (window != null) { window.getSelectionService().removePostSelectionListener(this); } IWorkbenchWindow activeWindow = JavaPlugin.getActiveWorkbenchWindow(); if (activeWindow != null) { IWorkbenchPage activePage = activeWindow.getActivePage(); if (activePage != null) { IEditorReference[] openEditors = activePage.getEditorReferences(); if (openEditors.length != 0) { // remove the part listener for each open editor for (int i = 0; i < openEditors.length; i++) { openEditors[i].getPage().removePartListener(this); } } } } persistSettings(); XReferenceUIPlugin.xrefView = null; viewer.getTree().dispose(); if (viewer.getContentProvider() != null) { viewer.getContentProvider().dispose(); } viewer.getLabelProvider().dispose(); } public boolean isLinkingEnabled() { return linkingEnabled; } public void setLinkingEnabled(boolean isOn) { linkingEnabled = isOn; if (linkingEnabled) { // calculate the xrefs for the last selected JavaElement List xraList = null; if (showXRefsForFileEnabled) { xraList = XRefUIUtils.getXRefAdapterListForJavaElement(lastJavaElement, true); } else { xraList = XRefUIUtils.getXRefAdapterListForJavaElement(lastJavaElement, false); } viewer.setInput(xraList); } } public boolean isShowXRefsForFileEnabled() { return showXRefsForFileEnabled; } public void setShowXRefsForFileEnabled(boolean isOn) { showXRefsForFileEnabled = isOn; List xraList = null; IWorkbenchPart part = null; if (!linkingEnabled) { // if linking is not enabled then just want to show/hide the cross // references // for the file of the contents of the xref view if (lastLinkedSelection != null && lastLinkedWorkbenchPart != null) { part = lastLinkedWorkbenchPart; if (showXRefsForFileEnabled) { xraList = XRefUIUtils.getXRefAdapterListForJavaElement(lastLinkedJavaElement, true); } else { xraList = XRefUIUtils.getXRefAdapterListForJavaElement(lastLinkedJavaElement, false); } } } else { // if linking is enabled, then want to show/hide the cross // references // for the file which is open in the active editor if (lastSelection != null && lastWorkbenchPart != null) { part = lastWorkbenchPart; if (showXRefsForFileEnabled) { xraList = XRefUIUtils.getXRefAdapterListForJavaElement(lastJavaElement, true); } else { xraList = XRefUIUtils.getXRefAdapterListForJavaElement(lastJavaElement, false); } } } if (xraList != null) { ISelection sel = viewer.getSelection(); viewer.setInput(xraList); XRefUIUtils.setSelection(part, sel, viewer); } } public void collapseAll() { viewer.collapseAll(); } public ISelection getLastSelection() { return lastSelection; } public IWorkbenchPart getLastSelectedWorkbenchPart() { return lastWorkbenchPart; } private void persistSettings() { IPreferenceStore pstore = XReferenceUIPlugin.getDefault().getPreferenceStore(); if (!pstore.contains(LINK_ID)) { pstore.setDefault(LINK_ID, true); } pstore.setValue(LINK_ID, linkingEnabled); if (!pstore.contains(XREFS_FOR_FILE_ID)) { pstore.setDefault(XREFS_FOR_FILE_ID, false); } pstore.setValue(XREFS_FOR_FILE_ID, showXRefsForFileEnabled); XReferenceUIPlugin.getDefault().savePluginPreferences(); } private void restorePersistedSettings() { IPreferenceStore pstore = XReferenceUIPlugin.getDefault().getPreferenceStore(); if (pstore.contains(LINK_ID)) { linkingEnabled = pstore.getBoolean(LINK_ID); } if (pstore.contains(XREFS_FOR_FILE_ID)) { showXRefsForFileEnabled = pstore.getBoolean(XREFS_FOR_FILE_ID); } } private void contributeToActionBars() { IActionBars bars = getViewSite().getActionBars(); fillLocalPullDown(bars.getMenuManager()); fillLocalToolBar(bars.getToolBarManager()); // Add global action handlers. bars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction); bars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), selectAllAction); } private void fillLocalPullDown(IMenuManager manager) { manager.add(new Separator()); manager.add(toggleLinkingAction); manager.add(toggleShowXRefsForFileAction); manager.add(new Separator("filters")); //$NON-NLS-1$ manager.add(xRefCustomFilterAction); } private void fillLocalToolBar(IToolBarManager manager) { manager.add(new Separator()); manager.add(collapseAllAction); manager.add(toggleLinkingAction); manager.add(toggleShowXRefsForFileAction); } private void hookDoubleClickAction() { viewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { doubleClickAction.run(); } }); } private void makeActions() { toggleLinkingAction = new ToggleLinkingAction(this); collapseAllAction = new CollapseAllAction(this); doubleClickAction = new DoubleClickAction(getViewSite().getShell(), viewer); toggleShowXRefsForFileAction = new ToggleShowXRefsForFileAction(this); xRefCustomFilterAction = new XReferenceCustomFilterAction(getSite().getShell()); copyAction = new CopyAction(viewer, fClipboard); selectAllAction = new SelectAllAction(viewer); } // fix for bug (no number) raised which said that xref view didn't // clear when there were no open editors private void addListenersToOpenEditors() { IWorkbenchWindow activeWindow = JavaPlugin.getActiveWorkbenchWindow(); if (activeWindow != null) { IWorkbenchPage activePage = activeWindow.getActivePage(); if (activePage != null) { IEditorReference[] openEditors = activePage.getEditorReferences(); if (openEditors.length != 0) { // add a part listener to each open editor for (int i = 0; i < openEditors.length; i++) { openEditors[i].getPage().addPartListener(this); } } } } } /** * @param changeDrivenByBuild * The changeDrivenByBuild to set. */ public void setChangeDrivenByBuild(boolean changeDrivenByBuild) { this.changeDrivenByBuild = changeDrivenByBuild; } // ----------------- IPartLisenter implementation ---------------------- /* * (non-Javadoc) * * @see org.eclipse.ui.IPartListener#partActivated(org.eclipse.ui.IWorkbenchPart) */ public void partActivated(IWorkbenchPart part) { } /* * (non-Javadoc) * * @see org.eclipse.ui.IPartListener#partBroughtToTop(org.eclipse.ui.IWorkbenchPart) */ public void partBroughtToTop(IWorkbenchPart part) { } /* * (non-Javadoc) * * @see org.eclipse.ui.IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart) */ public void partClosed(IWorkbenchPart part) { if (part instanceof IEditorPart) { IWorkbenchWindow activeWindow = JavaPlugin.getActiveWorkbenchWindow(); if (activeWindow != null) { IWorkbenchPage activePage = activeWindow.getActivePage(); if (activePage != null) { IEditorReference[] openEditors = activePage.getEditorReferences(); if (openEditors.length == 0) { // if there are no editors open, then want to clear the // contents of the xref view and all the records clearView(); if (linkingEnabled) { lastXRefAdapterList = null; lastSelection = null; lastWorkbenchPart = null; lastJavaElement = null; } } } } } } private void clearView() { if (viewer != null && viewer.getContentProvider() != null) { viewer.setInput(null); } } /* * (non-Javadoc) * * @see org.eclipse.ui.IPartListener#partDeactivated(org.eclipse.ui.IWorkbenchPart) */ public void partDeactivated(IWorkbenchPart part) { } /* * (non-Javadoc) * * @see org.eclipse.ui.IPartListener#partOpened(org.eclipse.ui.IWorkbenchPart) */ public void partOpened(IWorkbenchPart part) { } public Object getAdapter(Class key) { if (key.equals(IContextProvider.class)) { return XRefUIHelp.getHelpContextProvider(this, IXRefHelpContextIds.XREF_VIEW); } return super.getAdapter(key); } // ----------------- This is for testing ---------------------- /** * Returns the tree viewer for the xref view - this method is for testing * purposes and not part of the published API. */ public TreeViewer getTreeViewer() { return viewer; } /** * Returns the action for the xref view - this method is for testing * purposes and not part of the published API. */ public Action getCustomFilterAction() { return xRefCustomFilterAction; } /** * Returns the action for the xref view - this method is for testing * purposes and not part of the published API. */ public Action getToggleShowXRefsForEntireFileAction() { return toggleShowXRefsForFileAction; } /** * Returns the action for the xref view - this method is for testing * purposes and not part of the published API. */ public Action getToggleLinkWithEditorAction() { return toggleLinkingAction; } }