| /******************************************************************************* |
| * Copyright (c) 2000, 2006 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.eclipse.ui.internal; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| import org.eclipse.jface.action.ContributionItem; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.action.IContributionItem; |
| import org.eclipse.jface.action.IMenuListener; |
| import org.eclipse.jface.action.IMenuManager; |
| 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.widgets.Menu; |
| import org.eclipse.swt.widgets.MenuItem; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.internal.util.Util; |
| import org.eclipse.ui.part.IShowInSource; |
| import org.eclipse.ui.part.IShowInTargetList; |
| import org.eclipse.ui.part.ShowInContext; |
| import org.eclipse.ui.views.IViewDescriptor; |
| import org.eclipse.ui.views.IViewRegistry; |
| |
| /** |
| * A <code>ShowInMenu</code> is used to populate a menu manager with |
| * Show In actions. The items to show are determined from the active perspective |
| * and active part. |
| */ |
| public class ShowInMenu extends ContributionItem { |
| |
| private static final String NO_TARGETS_MSG = WorkbenchMessages.Workbench_showInNoTargets; |
| |
| private IWorkbenchWindow window; |
| |
| private Map actions = new HashMap(21); |
| |
| private boolean dirty = true; |
| |
| private IMenuListener menuListener = new IMenuListener() { |
| public void menuAboutToShow(IMenuManager manager) { |
| manager.markDirty(); |
| dirty = true; |
| } |
| }; |
| |
| /** |
| * Creates a Show In menu. |
| * |
| * @param window the window containing the menu |
| */ |
| public ShowInMenu(IWorkbenchWindow window, String id) { |
| super(id); |
| this.window = window; |
| } |
| |
| protected IWorkbenchWindow getWindow() { |
| return window; |
| } |
| |
| public boolean isDirty() { |
| return dirty; |
| } |
| |
| /** |
| * Overridden to always return true and force dynamic menu building. |
| */ |
| public boolean isDynamic() { |
| return true; |
| } |
| |
| public void fill(Menu menu, int index) { |
| if (getParent() instanceof MenuManager) { |
| ((MenuManager) getParent()).addMenuListener(menuListener); |
| } |
| |
| if (!dirty) { |
| return; |
| } |
| |
| MenuManager manager = new MenuManager(); |
| fillMenu(manager); |
| IContributionItem[] items = manager.getItems(); |
| if (items.length == 0) { |
| MenuItem item = new MenuItem(menu, SWT.NONE, index++); |
| item.setText(NO_TARGETS_MSG); |
| item.setEnabled(false); |
| } else { |
| for (int i = 0; i < items.length; i++) { |
| items[i].fill(menu, index++); |
| } |
| } |
| dirty = false; |
| } |
| |
| /** |
| * Fills the menu with Show In actions. |
| */ |
| private void fillMenu(IMenuManager innerMgr) { |
| // Remove all. |
| innerMgr.removeAll(); |
| |
| IWorkbenchPart sourcePart = getSourcePart(); |
| if (sourcePart == null) { |
| return; |
| } |
| ShowInContext context = getContext(sourcePart); |
| if (context == null) { |
| return; |
| } |
| if (context.getInput() == null |
| && (context.getSelection() == null || context.getSelection() |
| .isEmpty())) { |
| return; |
| } |
| |
| IViewDescriptor[] viewDescs = getViewDescriptors(sourcePart); |
| if (viewDescs.length == 0) { |
| return; |
| } |
| |
| for (int i = 0; i < viewDescs.length; ++i) { |
| IAction action = getAction(viewDescs[i]); |
| if (action != null) { |
| innerMgr.add(action); |
| } |
| } |
| } |
| |
| /** |
| * Returns the action for the given view id, or null if not found. |
| */ |
| private IAction getAction(IViewDescriptor desc) { |
| // Keep a cache, rather than creating a new action each time, |
| // so that image caching in ActionContributionItem works. |
| IAction action = (IAction) actions.get(desc.getId()); |
| if (action == null) { |
| if (desc != null) { |
| action = new ShowInAction(window, desc); |
| actions.put(desc.getId(), action); |
| } |
| } |
| return action; |
| } |
| |
| /** |
| * Returns the Show In... target part ids for the given source part. |
| * Merges the contributions from the current perspective and the source part. |
| */ |
| private ArrayList getShowInPartIds(IWorkbenchPart sourcePart) { |
| ArrayList targetIds = new ArrayList(); |
| WorkbenchPage page = (WorkbenchPage) getWindow().getActivePage(); |
| if (page != null) { |
| targetIds.addAll(page.getShowInPartIds()); |
| } |
| IShowInTargetList targetList = getShowInTargetList(sourcePart); |
| if (targetList != null) { |
| String[] partIds = targetList.getShowInTargetIds(); |
| if (partIds != null) { |
| for (int i = 0; i < partIds.length; ++i) { |
| if (!targetIds.contains(partIds[i])) { |
| targetIds.add(partIds[i]); |
| } |
| } |
| } |
| } |
| page.sortShowInPartIds(targetIds); |
| return targetIds; |
| } |
| |
| /** |
| * Returns the source part, or <code>null</code> if there is no applicable |
| * source part |
| * <p> |
| * This implementation returns the current part in the window. |
| * Subclasses may extend or reimplement. |
| * |
| * @return the source part or <code>null</code> |
| */ |
| private IWorkbenchPart getSourcePart() { |
| IWorkbenchPage page = getWindow().getActivePage(); |
| if (page != null) { |
| return page.getActivePart(); |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the <code>IShowInSource</code> provided by the source part, |
| * or <code>null</code> if it does not provide one. |
| * |
| * @param sourcePart the source part |
| * @return an <code>IShowInSource</code> or <code>null</code> |
| */ |
| private IShowInSource getShowInSource(IWorkbenchPart sourcePart) { |
| return (IShowInSource)Util.getAdapter(sourcePart, IShowInSource.class); |
| } |
| |
| /** |
| * Returns the <code>IShowInTargetList</code> for the given source part, |
| * or <code>null</code> if it does not provide one. |
| * |
| * @param sourcePart the source part |
| * @return the <code>IShowInTargetList</code> or <code>null</code> |
| */ |
| private IShowInTargetList getShowInTargetList(IWorkbenchPart sourcePart) { |
| return (IShowInTargetList)Util.getAdapter(sourcePart, IShowInTargetList.class); |
| } |
| |
| /** |
| * Returns the <code>ShowInContext</code> to show in the selected target, |
| * or <code>null</code> if there is no valid context to show. |
| * <p> |
| * This implementation obtains the context from the <code>IShowInSource</code> |
| * of the source part (if provided), or, if the source part is an editor, |
| * it creates the context from the editor's input and selection. |
| * <p> |
| * Subclasses may extend or reimplement. |
| * |
| * @return the <code>ShowInContext</code> to show or <code>null</code> |
| */ |
| private ShowInContext getContext(IWorkbenchPart sourcePart) { |
| IShowInSource source = getShowInSource(sourcePart); |
| if (source != null) { |
| ShowInContext context = source.getShowInContext(); |
| if (context != null) { |
| return context; |
| } |
| } else if (sourcePart instanceof IEditorPart) { |
| Object input = ((IEditorPart) sourcePart).getEditorInput(); |
| ISelectionProvider sp = sourcePart.getSite().getSelectionProvider(); |
| ISelection sel = sp == null ? null : sp.getSelection(); |
| return new ShowInContext(input, sel); |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the view descriptors to show in the dialog. |
| */ |
| private IViewDescriptor[] getViewDescriptors(IWorkbenchPart sourcePart) { |
| String srcId = sourcePart.getSite().getId(); |
| ArrayList ids = getShowInPartIds(sourcePart); |
| ArrayList descs = new ArrayList(); |
| IViewRegistry reg = WorkbenchPlugin.getDefault().getViewRegistry(); |
| for (Iterator i = ids.iterator(); i.hasNext();) { |
| String id = (String) i.next(); |
| if (!id.equals(srcId)) { |
| IViewDescriptor desc = reg.find(id); |
| if (desc != null) { |
| descs.add(desc); |
| } |
| } |
| } |
| return (IViewDescriptor[]) descs.toArray(new IViewDescriptor[descs |
| .size()]); |
| } |
| |
| } |