/******************************************************************************* * Copyright (c) 2000, 2005 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 *******************************************************************************/ package org.erlide.ui.views; import org.eclipse.jface.action.IAction; 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.ISelection; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IPartListener2; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.ViewPart; import org.erlide.ui.internal.ErlBrowserInformationControlInput; import org.erlide.ui.internal.ErlideUIPlugin; /** * Abstract class for views which show information for a given element. * * @since 3.0 */ abstract public class AbstractInfoView extends ViewPart implements ISelectionListener, IMenuListener { /* * @see IPartListener2 */ private final IPartListener2 fPartListener = new IPartListener2() { @Override public void partVisible(final IWorkbenchPartReference ref) { if (ref.getId().equals(getSite().getId())) { final IWorkbenchPart activePart = ref.getPage().getActivePart(); if (activePart != null) { selectionChanged(activePart, ref.getPage().getSelection()); } startListeningForSelectionChanges(); } } @Override public void partHidden(final IWorkbenchPartReference ref) { if (ref.getId().equals(getSite().getId())) { stopListeningForSelectionChanges(); } } @Override public void partInputChanged(final IWorkbenchPartReference ref) { if (!ref.getId().equals(getSite().getId())) { computeAndSetInput(ref.getPart(false)); } } @Override public void partActivated(final IWorkbenchPartReference ref) { } @Override public void partBroughtToTop(final IWorkbenchPartReference ref) { } @Override public void partClosed(final IWorkbenchPartReference ref) { } @Override public void partDeactivated(final IWorkbenchPartReference ref) { } @Override public void partOpened(final IWorkbenchPartReference ref) { } }; /** The current info. */ protected Object fCurrentViewInfo; /** Counts the number of background computation requests. */ volatile int fComputeCount; /** * Set the input of this view. * * @param input * the input object */ public abstract void setInfo(Object info); /** * Create the part control. * * @param parent * the parent control * @see IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) */ abstract protected void internalCreatePartControl(Composite parent); /** * Set the view's foreground color. * * @param color * the SWT color */ abstract protected void setForeground(Color color); /** * Set the view's background color. * * @param color * the SWT color */ abstract protected void setBackground(Color color); /** * Returns the view's primary control. * * @return the primary control */ abstract Control getControl(); abstract protected Object getInfoForSelection(IWorkbenchPart part, ISelection selection); /** * Returns the context ID for the Help system * * @return the string used as ID for the Help context * @since 3.1 */ abstract protected String getHelpContextId(); /* * @see IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) */ @Override public final void createPartControl(final Composite parent) { internalCreatePartControl(parent); setInfoColor(); getSite().getWorkbenchWindow().getPartService().addPartListener(fPartListener); createContextMenu(); createActions(); fillActionBars(getViewSite().getActionBars()); PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), getHelpContextId()); } /** * Creates the actions and action groups for this view. */ protected void createActions() { } /** * Creates the context menu for this view. */ protected void createContextMenu() { final MenuManager menuManager = new MenuManager("#PopupMenu"); //$NON-NLS-1$ menuManager.setRemoveAllWhenShown(true); menuManager.addMenuListener(this); final Menu contextMenu = menuManager.createContextMenu(getControl()); getControl().setMenu(contextMenu); } /* * @see IMenuListener#menuAboutToShow(org.eclipse.jface.action.IMenuManager) */ @Override public void menuAboutToShow(final IMenuManager menu) { ErlideUIPlugin.createStandardGroups(menu); } protected IAction getSelectAllAction() { return null; } /** * Returns the input of this view. * * @return input the input object or <code>null</code> if not input is set */ protected Object getInfo() { return fCurrentViewInfo; } /** * Fills the actions bars. * <p> * Subclasses may extend. * * @param actionBars * the action bars */ protected void fillActionBars(final IActionBars actionBars) { final IToolBarManager toolBar = actionBars.getToolBarManager(); fillToolBar(toolBar); } /** * Fills the tool bar. * <p> * Default is to do nothing. * </p> * * @param tbm * the tool bar manager */ protected void fillToolBar(final IToolBarManager tbm) { } /** * Sets the foreground and background color to the corresponding SWT info * color. */ private void setInfoColor() { if (getSite().getShell().isDisposed()) { return; } final Display display = getSite().getShell().getDisplay(); if (display == null || display.isDisposed()) { return; } setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND)); setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); } /** * Start to listen for selection changes. */ protected void startListeningForSelectionChanges() { getSite().getWorkbenchWindow().getSelectionService() .addPostSelectionListener(this); } /** * Stop to listen for selection changes. */ protected void stopListeningForSelectionChanges() { getSite().getWorkbenchWindow().getSelectionService() .removePostSelectionListener(this); } /* * @see ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, * org.eclipse.jface.viewers.ISelection) */ @Override public void selectionChanged(final IWorkbenchPart part, final ISelection selection) { if (part.equals(this)) { return; } computeAndSetInput(part); } /** * Tells whether the new input should be ignored if the current input is the * same. * * @return <code>true</code> if the new input should be ignored */ protected boolean isIgnoringEqualInput() { return true; } // /** // * Finds and returns the Erlang element selected in the given part. // * // * @param part the workbench part for which to find the selected Erlang // element // * @param selection the selection // * @return the selected Erlang element // */ // protected IErlElement findSelectedJavaElement(IWorkbenchPart part, // ISelection // selection) { // Object element; // try { // if (part instanceof ErlangEditor && selection instanceof ITextSelection) // { // IErlElement[] elements= // TextSelectionConverter.codeResolve((JavaEditor)part, // (ITextSelection)selection); // if (elements != null && elements.length > 0) // return elements[0]; // else // return null; // } else if (selection instanceof IStructuredSelection) { // element= element= SelectionUtil.getSingleElement(selection); // } else { // return null; // } // } catch (JavaModelException e) { // return null; // } // // return findJavaElement(element); // } // /** // * Tries to get a Java element out of the given element. // * // * @param element an object // * @return the Java element represented by the given element or // <code>null</code> // */ // private IErlElement findJavaElement(Object element) { // // if (element == null) // return null; // // IErlElement je= null; // if (element instanceof IAdaptable) // je= (IErlElement)((IAdaptable)element).getAdapter(IErlElement.class); // // return je; // } // /** // * Finds and returns the type for the given CU. // * // * @param cu the compilation unit // * @return the type with same name as the given CU or the first type in // the CU // */ // protected IType getTypeForCU(ICompilationUnit cu) { // // if (cu == null || !cu.exists()) // return null; // // // Use primary type if possible // IType primaryType= cu.findPrimaryType(); // if (primaryType != null) // return primaryType; // // // Use first top-level type // try { // IType[] types= cu.getTypes(); // if (types.length > 0) // return types[0]; // else // return null; // } catch (JavaModelException ex) { // return null; // } // } /* * @see IWorkbenchPart#dispose() */ @Override final public void dispose() { // cancel possible running computation synchronized (this) { fComputeCount--; } getSite().getWorkbenchWindow().getPartService().removePartListener(fPartListener); internalDispose(); } /* * @see IWorkbenchPart#dispose() */ protected void internalDispose() { } /** * Determines all necessary details and delegates the computation into a * background thread. * * @param part * the workbench part */ void computeAndSetInput(final IWorkbenchPart part) { final int currentCount = ++fComputeCount; final ISelectionProvider provider = part.getSite().getSelectionProvider(); if (provider == null) { return; } final ISelection selection = provider.getSelection(); if (selection == null || selection.isEmpty()) { return; } final Thread thread = new Thread("Info view input computer") { //$NON-NLS-1$ @Override public void run() { if (currentCount != fComputeCount) { return; } // final IErlElement je= findSelectedJavaElement(part, // selection); final Object info = getInfoForSelection(part, selection); if (info == null || info instanceof ErlBrowserInformationControlInput && ((ErlBrowserInformationControlInput) info).getHtml() .length() == 0) { return; } final Shell shell = getSite().getShell(); if (shell.isDisposed()) { return; } final Display display = shell.getDisplay(); if (display.isDisposed()) { return; } display.asyncExec(new Runnable() { /* * @see java.lang.Runnable#run() */ @Override public void run() { if (fComputeCount != currentCount || getViewSite().getShell().isDisposed()) { return; } fCurrentViewInfo = info; doSetInfo(info); } }); } }; thread.setDaemon(true); thread.setPriority(Thread.MIN_PRIORITY); thread.start(); } protected void doSetInfo(final Object info) { setInfo(info); } }