001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal;
011:
012: import java.util.ArrayList;
013: import java.util.HashMap;
014: import java.util.Iterator;
015: import java.util.Map;
016:
017: import org.eclipse.jface.action.ContributionItem;
018: import org.eclipse.jface.action.IAction;
019: import org.eclipse.jface.action.IContributionItem;
020: import org.eclipse.jface.action.IMenuListener;
021: import org.eclipse.jface.action.IMenuManager;
022: import org.eclipse.jface.action.MenuManager;
023: import org.eclipse.jface.viewers.ISelection;
024: import org.eclipse.jface.viewers.ISelectionProvider;
025: import org.eclipse.swt.SWT;
026: import org.eclipse.swt.widgets.Menu;
027: import org.eclipse.swt.widgets.MenuItem;
028: import org.eclipse.ui.IEditorPart;
029: import org.eclipse.ui.IWorkbenchPage;
030: import org.eclipse.ui.IWorkbenchPart;
031: import org.eclipse.ui.IWorkbenchWindow;
032: import org.eclipse.ui.internal.util.Util;
033: import org.eclipse.ui.part.IShowInSource;
034: import org.eclipse.ui.part.IShowInTargetList;
035: import org.eclipse.ui.part.ShowInContext;
036: import org.eclipse.ui.views.IViewDescriptor;
037: import org.eclipse.ui.views.IViewRegistry;
038:
039: /**
040: * A <code>ShowInMenu</code> is used to populate a menu manager with
041: * Show In actions. The items to show are determined from the active perspective
042: * and active part.
043: */
044: public class ShowInMenu extends ContributionItem {
045:
046: private static final String NO_TARGETS_MSG = WorkbenchMessages.Workbench_showInNoTargets;
047:
048: private IWorkbenchWindow window;
049:
050: private Map actions = new HashMap(21);
051:
052: private boolean dirty = true;
053:
054: private IMenuListener menuListener = new IMenuListener() {
055: public void menuAboutToShow(IMenuManager manager) {
056: manager.markDirty();
057: dirty = true;
058: }
059: };
060:
061: /**
062: * Creates a Show In menu.
063: *
064: * @param window the window containing the menu
065: */
066: public ShowInMenu(IWorkbenchWindow window, String id) {
067: super (id);
068: this .window = window;
069: }
070:
071: protected IWorkbenchWindow getWindow() {
072: return window;
073: }
074:
075: public boolean isDirty() {
076: return dirty;
077: }
078:
079: /**
080: * Overridden to always return true and force dynamic menu building.
081: */
082: public boolean isDynamic() {
083: return true;
084: }
085:
086: public void fill(Menu menu, int index) {
087: if (getParent() instanceof MenuManager) {
088: ((MenuManager) getParent()).addMenuListener(menuListener);
089: }
090:
091: if (!dirty) {
092: return;
093: }
094:
095: MenuManager manager = new MenuManager();
096: fillMenu(manager);
097: IContributionItem[] items = manager.getItems();
098: if (items.length == 0) {
099: MenuItem item = new MenuItem(menu, SWT.NONE, index++);
100: item.setText(NO_TARGETS_MSG);
101: item.setEnabled(false);
102: } else {
103: for (int i = 0; i < items.length; i++) {
104: items[i].fill(menu, index++);
105: }
106: }
107: dirty = false;
108: }
109:
110: /**
111: * Fills the menu with Show In actions.
112: */
113: private void fillMenu(IMenuManager innerMgr) {
114: // Remove all.
115: innerMgr.removeAll();
116:
117: IWorkbenchPart sourcePart = getSourcePart();
118: if (sourcePart == null) {
119: return;
120: }
121: ShowInContext context = getContext(sourcePart);
122: if (context == null) {
123: return;
124: }
125: if (context.getInput() == null
126: && (context.getSelection() == null || context
127: .getSelection().isEmpty())) {
128: return;
129: }
130:
131: IViewDescriptor[] viewDescs = getViewDescriptors(sourcePart);
132: if (viewDescs.length == 0) {
133: return;
134: }
135:
136: for (int i = 0; i < viewDescs.length; ++i) {
137: IAction action = getAction(viewDescs[i]);
138: if (action != null) {
139: innerMgr.add(action);
140: }
141: }
142: }
143:
144: /**
145: * Returns the action for the given view id, or null if not found.
146: */
147: private IAction getAction(IViewDescriptor desc) {
148: // Keep a cache, rather than creating a new action each time,
149: // so that image caching in ActionContributionItem works.
150: IAction action = (IAction) actions.get(desc.getId());
151: if (action == null) {
152: if (desc != null) {
153: action = new ShowInAction(window, desc);
154: actions.put(desc.getId(), action);
155: }
156: }
157: return action;
158: }
159:
160: /**
161: * Returns the Show In... target part ids for the given source part.
162: * Merges the contributions from the current perspective and the source part.
163: */
164: private ArrayList getShowInPartIds(IWorkbenchPart sourcePart) {
165: ArrayList targetIds = new ArrayList();
166: WorkbenchPage page = (WorkbenchPage) getWindow()
167: .getActivePage();
168: if (page != null) {
169: targetIds.addAll(page.getShowInPartIds());
170: }
171: IShowInTargetList targetList = getShowInTargetList(sourcePart);
172: if (targetList != null) {
173: String[] partIds = targetList.getShowInTargetIds();
174: if (partIds != null) {
175: for (int i = 0; i < partIds.length; ++i) {
176: if (!targetIds.contains(partIds[i])) {
177: targetIds.add(partIds[i]);
178: }
179: }
180: }
181: }
182: page.sortShowInPartIds(targetIds);
183: return targetIds;
184: }
185:
186: /**
187: * Returns the source part, or <code>null</code> if there is no applicable
188: * source part
189: * <p>
190: * This implementation returns the current part in the window.
191: * Subclasses may extend or reimplement.
192: *
193: * @return the source part or <code>null</code>
194: */
195: private IWorkbenchPart getSourcePart() {
196: IWorkbenchPage page = getWindow().getActivePage();
197: if (page != null) {
198: return page.getActivePart();
199: }
200: return null;
201: }
202:
203: /**
204: * Returns the <code>IShowInSource</code> provided by the source part,
205: * or <code>null</code> if it does not provide one.
206: *
207: * @param sourcePart the source part
208: * @return an <code>IShowInSource</code> or <code>null</code>
209: */
210: private IShowInSource getShowInSource(IWorkbenchPart sourcePart) {
211: return (IShowInSource) Util.getAdapter(sourcePart,
212: IShowInSource.class);
213: }
214:
215: /**
216: * Returns the <code>IShowInTargetList</code> for the given source part,
217: * or <code>null</code> if it does not provide one.
218: *
219: * @param sourcePart the source part
220: * @return the <code>IShowInTargetList</code> or <code>null</code>
221: */
222: private IShowInTargetList getShowInTargetList(
223: IWorkbenchPart sourcePart) {
224: return (IShowInTargetList) Util.getAdapter(sourcePart,
225: IShowInTargetList.class);
226: }
227:
228: /**
229: * Returns the <code>ShowInContext</code> to show in the selected target,
230: * or <code>null</code> if there is no valid context to show.
231: * <p>
232: * This implementation obtains the context from the <code>IShowInSource</code>
233: * of the source part (if provided), or, if the source part is an editor,
234: * it creates the context from the editor's input and selection.
235: * <p>
236: * Subclasses may extend or reimplement.
237: *
238: * @return the <code>ShowInContext</code> to show or <code>null</code>
239: */
240: private ShowInContext getContext(IWorkbenchPart sourcePart) {
241: IShowInSource source = getShowInSource(sourcePart);
242: if (source != null) {
243: ShowInContext context = source.getShowInContext();
244: if (context != null) {
245: return context;
246: }
247: } else if (sourcePart instanceof IEditorPart) {
248: Object input = ((IEditorPart) sourcePart).getEditorInput();
249: ISelectionProvider sp = sourcePart.getSite()
250: .getSelectionProvider();
251: ISelection sel = sp == null ? null : sp.getSelection();
252: return new ShowInContext(input, sel);
253: }
254: return null;
255: }
256:
257: /**
258: * Returns the view descriptors to show in the dialog.
259: */
260: private IViewDescriptor[] getViewDescriptors(
261: IWorkbenchPart sourcePart) {
262: String srcId = sourcePart.getSite().getId();
263: ArrayList ids = getShowInPartIds(sourcePart);
264: ArrayList descs = new ArrayList();
265: IViewRegistry reg = WorkbenchPlugin.getDefault()
266: .getViewRegistry();
267: for (Iterator i = ids.iterator(); i.hasNext();) {
268: String id = (String) i.next();
269: if (!id.equals(srcId)) {
270: IViewDescriptor desc = reg.find(id);
271: if (desc != null) {
272: descs.add(desc);
273: }
274: }
275: }
276: return (IViewDescriptor[]) descs
277: .toArray(new IViewDescriptor[descs.size()]);
278: }
279:
280: }
|