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 org.eclipse.core.expressions.Expression;
013: import org.eclipse.jface.action.ActionContributionItem;
014: import org.eclipse.jface.action.ContributionManager;
015: import org.eclipse.jface.action.GroupMarker;
016: import org.eclipse.jface.action.IContributionItem;
017: import org.eclipse.jface.action.IContributionManager;
018: import org.eclipse.jface.action.IContributionManagerOverrides;
019: import org.eclipse.jface.action.ICoolBarManager;
020: import org.eclipse.jface.action.IMenuManager;
021: import org.eclipse.jface.action.IToolBarManager;
022: import org.eclipse.jface.action.SubContributionManager;
023: import org.eclipse.jface.action.SubMenuManager;
024: import org.eclipse.jface.action.SubStatusLineManager;
025: import org.eclipse.jface.action.SubToolBarManager;
026: import org.eclipse.jface.internal.provisional.action.IToolBarContributionItem;
027: import org.eclipse.ui.IActionBars2;
028: import org.eclipse.ui.IEditorActionBarContributor;
029: import org.eclipse.ui.IEditorPart;
030: import org.eclipse.ui.IWorkbenchActionConstants;
031: import org.eclipse.ui.IWorkbenchPart;
032: import org.eclipse.ui.SubActionBars2;
033: import org.eclipse.ui.actions.RetargetAction;
034: import org.eclipse.ui.internal.expressions.LegacyEditorActionBarExpression;
035: import org.eclipse.ui.internal.misc.Policy;
036: import org.eclipse.ui.internal.provisional.presentations.IActionBarPresentationFactory;
037: import org.eclipse.ui.services.IServiceLocator;
038:
039: /**
040: * The action bars for an editor.
041: */
042: public class EditorActionBars extends SubActionBars2 {
043:
044: private class Overrides implements IContributionManagerOverrides {
045:
046: public Integer getAccelerator(IContributionItem item) {
047: return null;
048: }
049:
050: public String getAcceleratorText(IContributionItem item) {
051: return null;
052: }
053:
054: public Boolean getEnabled(IContributionItem item) {
055: if (((item instanceof ActionContributionItem) && (((ActionContributionItem) item)
056: .getAction() instanceof RetargetAction))
057: || enabledAllowed) {
058: return null;
059: } else {
060: return Boolean.FALSE;
061: }
062: }
063:
064: public String getText(IContributionItem item) {
065: return null;
066: }
067: }
068:
069: /**
070: * A switch controlling verbose debugging options surrounding the disposal
071: * of tool bar contribution items. There have been problems in the past with
072: * reusing disposed items, and leaking memory by failing to drop references
073: * to disposed items.
074: */
075: private static final boolean DEBUG_TOOLBAR_DISPOSAL = Policy.DEBUG_TOOLBAR_DISPOSAL;
076:
077: private IToolBarManager coolItemToolBarMgr = null;
078:
079: private IEditorActionBarContributor editorContributor;
080:
081: private boolean enabledAllowed = false;
082:
083: private IEditorActionBarContributor extensionContributor;
084:
085: private int refCount;
086:
087: private IToolBarContributionItem toolBarContributionItem = null;
088:
089: private String type;
090:
091: private IActionBarPresentationFactory actionBarPresentation;
092:
093: /**
094: * Constructs the EditorActionBars for an editor.
095: */
096: public EditorActionBars(WorkbenchPage page,
097: final IServiceLocator serviceLocator, String type) {
098: super ((IActionBars2) page.getActionBars(), serviceLocator);
099: this .type = type;
100: this .actionBarPresentation = ((WorkbenchWindow) page
101: .getWorkbenchWindow())
102: .getActionBarPresentationFactory();
103: }
104:
105: /**
106: * Activate the contributions.
107: */
108: public void activate(boolean forceVisibility) {
109: setActive(true, forceVisibility);
110: }
111:
112: /**
113: * Add one ref to the bars.
114: */
115: public void addRef() {
116: ++refCount;
117: }
118:
119: /*
120: * (non-Javadoc) Method declared on SubActionBars.
121: */
122: protected SubMenuManager createSubMenuManager(IMenuManager parent) {
123: return new EditorMenuManager(parent);
124: }
125:
126: /*
127: * (non-Javadoc) Method declared on SubActionBars.
128: */
129: protected SubToolBarManager createSubToolBarManager(
130: IToolBarManager parent) {
131: // return null, editor actions are managed by CoolItemToolBarManagers
132: return null;
133: }
134:
135: /**
136: * Deactivate the contributions.
137: */
138: public void deactivate(boolean forceVisibility) {
139: setActive(false, forceVisibility);
140: }
141:
142: /**
143: * Dispose the contributions.
144: */
145: public void dispose() {
146: super .dispose();
147: if (editorContributor != null) {
148: editorContributor.dispose();
149: }
150: if (extensionContributor != null) {
151: extensionContributor.dispose();
152: }
153:
154: /*
155: * Dispose of the contribution item, but also make sure that no one else
156: * is holding on to it. In this case, go through the SubCoolBarManager
157: * to its parent (the real CoolBarManager), and replace the reference
158: * with a placeholder.
159: */
160: if (toolBarContributionItem != null) {
161: // Create a placeholder and place it in the cool bar manager.
162: ICoolBarManager coolBarManager = getCoolBarManager();
163: if (coolBarManager instanceof SubContributionManager) {
164: SubContributionManager subManager = (SubContributionManager) coolBarManager;
165: IContributionManager manager = subManager.getParent();
166: if (manager instanceof ContributionManager) {
167: final IContributionItem replacementItem = new PlaceholderContributionItem(
168: toolBarContributionItem);
169: boolean succeeded = ((ContributionManager) manager)
170: .replaceItem(replacementItem.getId(),
171: replacementItem);
172: if (!succeeded && DEBUG_TOOLBAR_DISPOSAL) {
173: System.out
174: .println("FAILURE WHILE DISPOSING EditorActionBars"); //$NON-NLS-1$
175: System.out
176: .println("Could not replace " + replacementItem.getId() + " in the contribution manager."); //$NON-NLS-1$ //$NON-NLS-2$
177: }
178: } else if (DEBUG_TOOLBAR_DISPOSAL) {
179: System.out
180: .println("FAILURE WHILE DISPOSING EditorActionBars"); //$NON-NLS-1$
181: System.out
182: .println("The manager was not a ContributionManager."); //$NON-NLS-1$
183: System.out
184: .println("It was a " + manager.getClass().getName()); //$NON-NLS-1$
185: }
186: } else if (DEBUG_TOOLBAR_DISPOSAL) {
187: System.out
188: .println("FAILURE WHILE DISPOSING EditorActionBars"); //$NON-NLS-1$
189: System.out
190: .println("The coolBarManager was not a SubContributionManager"); //$NON-NLS-1$
191: System.out
192: .println("It was a " + coolBarManager.getClass().getName()); //$NON-NLS-1$
193: }
194:
195: // Dispose of the replaced item.
196: toolBarContributionItem.dispose();
197: }
198: toolBarContributionItem = null;
199: // Remove actions
200: if (coolItemToolBarMgr != null) {
201: coolItemToolBarMgr.removeAll();
202: }
203: coolItemToolBarMgr = null;
204: editorHandlerExpression = null;
205: }
206:
207: /**
208: * Gets the editor contributor
209: */
210: public IEditorActionBarContributor getEditorContributor() {
211: return editorContributor;
212: }
213:
214: /**
215: * Returns the editor type.
216: */
217: public String getEditorType() {
218: return type;
219: }
220:
221: /**
222: * Gets the extension contributor
223: */
224: public IEditorActionBarContributor getExtensionContributor() {
225: return extensionContributor;
226: }
227:
228: /**
229: * Returns the reference count.
230: */
231: public int getRef() {
232: return refCount;
233: }
234:
235: /**
236: * Returns the tool bar manager. If items are added or removed from the
237: * manager be sure to call <code>updateActionBars</code>. Overridden to
238: * support CoolBars.
239: *
240: * @return the tool bar manager
241: */
242: public IToolBarManager getToolBarManager() {
243:
244: // by pass the sub coolBar and use the real cool bar.
245: ICoolBarManager coolBarManager = getCastedParent()
246: .getCoolBarManager();
247: if (coolBarManager == null) {
248: return null;
249: }
250:
251: // add the editor group if the app did not add it already,
252: // otherwise the references to it below will fail
253: if (coolBarManager.find(IWorkbenchActionConstants.GROUP_EDITOR) == null) {
254: coolBarManager.add(new GroupMarker(
255: IWorkbenchActionConstants.GROUP_EDITOR));
256: }
257: if (toolBarContributionItem == null) {
258: IContributionItem foundItem = coolBarManager.find(type);
259: if ((foundItem instanceof IToolBarContributionItem)) {
260: toolBarContributionItem = (IToolBarContributionItem) foundItem;
261: coolItemToolBarMgr = toolBarContributionItem
262: .getToolBarManager();
263: if (coolItemToolBarMgr == null) {
264: coolItemToolBarMgr = actionBarPresentation
265: .createToolBarManager();
266: toolBarContributionItem = actionBarPresentation
267: .createToolBarContributionItem(
268: coolItemToolBarMgr, type);
269: // Add editor item to group
270: coolBarManager.prependToGroup(
271: IWorkbenchActionConstants.GROUP_EDITOR,
272: toolBarContributionItem);
273: }
274: } else {
275: coolItemToolBarMgr = actionBarPresentation
276: .createToolBarManager();
277: if ((coolBarManager instanceof ContributionManager)
278: && (foundItem instanceof PlaceholderContributionItem)) {
279: PlaceholderContributionItem placeholder = (PlaceholderContributionItem) foundItem;
280: toolBarContributionItem = createToolBarContributionItem(
281: coolItemToolBarMgr, placeholder);
282: // Restore from a placeholder
283: ((ContributionManager) coolBarManager).replaceItem(
284: type, toolBarContributionItem);
285: } else {
286: toolBarContributionItem = actionBarPresentation
287: .createToolBarContributionItem(
288: coolItemToolBarMgr, type);
289: // Add editor item to group
290: coolBarManager.prependToGroup(
291: IWorkbenchActionConstants.GROUP_EDITOR,
292: toolBarContributionItem);
293: }
294: }
295: ((ContributionManager) coolItemToolBarMgr)
296: .setOverrides(new Overrides());
297: toolBarContributionItem.setVisible(getActive());
298: coolItemToolBarMgr.markDirty();
299: }
300:
301: return coolItemToolBarMgr;
302: }
303:
304: /*
305: * Creates a new tool bar contribution item on the given manager -- using
306: * the stored data to initialize some of its properties.
307: */
308: IToolBarContributionItem createToolBarContributionItem(
309: final IToolBarManager manager,
310: PlaceholderContributionItem item) {
311: IToolBarContributionItem toolBarContributionItem = actionBarPresentation
312: .createToolBarContributionItem(manager, item.getId());
313: toolBarContributionItem.setCurrentHeight(item.getHeight());
314: toolBarContributionItem.setCurrentWidth(item.getWidth());
315: toolBarContributionItem.setMinimumItemsToShow(item
316: .getMinimumItemsToShow());
317: toolBarContributionItem.setUseChevron(item.getUseChevron());
318: return toolBarContributionItem;
319: }
320:
321: /**
322: * Returns whether the contribution list is visible. If the visibility is
323: * <code>true</code> then each item within the manager appears within the
324: * parent manager. Otherwise, the items are not visible.
325: *
326: * @return <code>true</code> if the manager is visible
327: */
328: private boolean isVisible() {
329: if (toolBarContributionItem != null) {
330: return toolBarContributionItem.isVisible();
331: }
332: return false;
333: }
334:
335: /**
336: * Sets the target part for the action bars. For views this is ignored
337: * because each view has its own action vector. For editors this is
338: * important because the action vector is shared by editors of the same
339: * type.
340: */
341: public void partChanged(IWorkbenchPart part) {
342: super .partChanged(part);
343: if (part instanceof IEditorPart) {
344: IEditorPart editor = (IEditorPart) part;
345: if (editorContributor != null) {
346: editorContributor.setActiveEditor(editor);
347: }
348: if (extensionContributor != null) {
349: extensionContributor.setActiveEditor(editor);
350: }
351: }
352: }
353:
354: /**
355: * Remove one ref to the bars.
356: */
357: public void removeRef() {
358: --refCount;
359: }
360:
361: /**
362: * Activate / Deactivate the contributions.
363: *
364: * Workaround for flashing when editor contributes many menu/tool
365: * contributions. In this case, the force visibility flag determines if the
366: * contributions should be actually made visible/hidden or just change the
367: * enablement state.
368: */
369: private void setActive(boolean set, boolean forceVisibility) {
370: basicSetActive(set);
371: if (isSubMenuManagerCreated()) {
372: ((EditorMenuManager) getMenuManager()).setVisible(set,
373: forceVisibility);
374: }
375:
376: if (isSubStatusLineManagerCreated()) {
377: ((SubStatusLineManager) getStatusLineManager())
378: .setVisible(set);
379: }
380:
381: setVisible(set, forceVisibility);
382: }
383:
384: /**
385: * Sets the editor contributor
386: */
387: public void setEditorContributor(IEditorActionBarContributor c) {
388: editorContributor = c;
389: }
390:
391: /**
392: * Sets the enablement ability of all the items contributed by the editor.
393: *
394: * @param enabledAllowed
395: * <code>true</code> if the items may enable
396: * @since 2.0
397: */
398: private void setEnabledAllowed(boolean enabledAllowed) {
399: if (this .enabledAllowed == enabledAllowed) {
400: return;
401: }
402: this .enabledAllowed = enabledAllowed;
403: if (coolItemToolBarMgr != null) {
404: IContributionItem[] items = coolItemToolBarMgr.getItems();
405: for (int i = 0; i < items.length; i++) {
406: IContributionItem item = items[i];
407: item.update(IContributionManagerOverrides.P_ENABLED);
408: }
409: }
410: }
411:
412: /**
413: * Sets the extension contributor
414: */
415: public void setExtensionContributor(IEditorActionBarContributor c) {
416: extensionContributor = c;
417: }
418:
419: /**
420: * Sets the visibility of the manager. If the visibility is
421: * <code>true</code> then each item within the manager appears within the
422: * parent manager. Otherwise, the items are not visible.
423: *
424: * @param visible
425: * the new visibility
426: */
427: private void setVisible(boolean visible) {
428: if (toolBarContributionItem != null) {
429: toolBarContributionItem.setVisible(visible);
430: if (toolBarContributionItem.getParent() != null) {
431: toolBarContributionItem.getParent().markDirty();
432: }
433: }
434: }
435:
436: /**
437: * Sets the visibility of the manager. If the visibility is
438: * <code>true</code> then each item within the manager appears within the
439: * parent manager. Otherwise, the items are not visible if force visibility
440: * is <code>true</code>, or grayed out if force visibility is
441: * <code>false</code>
442: * <p>
443: * This is a workaround for the layout flashing when editors contribute
444: * large amounts of items.
445: * </p>
446: *
447: * @param visible
448: * the new visibility
449: * @param forceVisibility
450: * <code>true</code> to change the visibility or
451: * <code>false</code> to change just the enablement state. This
452: * parameter is ignored if visible is <code>true</code>.
453: */
454: private void setVisible(boolean visible, boolean forceVisibility) {
455: if (visible) {
456: setEnabledAllowed(true);
457: if (!isVisible()) {
458: setVisible(true);
459: }
460: } else {
461: if (forceVisibility) {
462: // Remove the editor tool bar items
463: setVisible(false);
464: } else {
465: // Disabled the tool bar items.
466: setEnabledAllowed(false);
467: }
468: }
469:
470: ICoolBarManager coolBarManager = getCastedParent()
471: .getCoolBarManager();
472: if ((coolItemToolBarMgr != null) && (coolBarManager != null)) {
473: IContributionItem[] items = coolItemToolBarMgr.getItems();
474: for (int i = 0; i < items.length; i++) {
475: IContributionItem item = items[i];
476: item.setVisible(visible || !forceVisibility);
477: coolItemToolBarMgr.markDirty();
478: if (!coolBarManager.isDirty()) {
479: coolBarManager.markDirty();
480: }
481: }
482: // Update the manager
483: coolItemToolBarMgr.update(false);
484: if (toolBarContributionItem != null) {
485: toolBarContributionItem.setVisible(visible
486: || !forceVisibility);
487: }
488: }
489: }
490:
491: private LegacyEditorActionBarExpression editorHandlerExpression = null;
492:
493: /**
494: * Returns the expression used for action handler activation.
495: * @return the expression used for action handler activation.
496: */
497: public Expression getHandlerExpression() {
498: if (editorHandlerExpression == null) {
499: editorHandlerExpression = new LegacyEditorActionBarExpression(
500: type);
501: }
502: return editorHandlerExpression;
503: }
504: }
|