001: /*******************************************************************************
002: * Copyright (c) 2004, 2007 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.actions;
011:
012: import org.eclipse.jface.action.ContributionItem;
013: import org.eclipse.jface.action.IContributionItem;
014: import org.eclipse.jface.action.IContributionManager;
015: import org.eclipse.jface.action.IMenuListener;
016: import org.eclipse.jface.action.IMenuManager;
017: import org.eclipse.swt.SWT;
018: import org.eclipse.swt.widgets.Menu;
019: import org.eclipse.swt.widgets.MenuItem;
020:
021: /**
022: * A compound contribution is a contribution item consisting of a
023: * dynamic list of contribution items.
024: *
025: * @since 3.1
026: */
027: public abstract class CompoundContributionItem extends ContributionItem {
028:
029: private boolean dirty = true;
030:
031: private IMenuListener menuListener = new IMenuListener() {
032: public void menuAboutToShow(IMenuManager manager) {
033: manager.markDirty();
034: dirty = true;
035: }
036: };
037:
038: private IContributionItem[] oldItems;
039:
040: /**
041: * Creates a compound contribution item with a <code>null</code> id.
042: */
043: protected CompoundContributionItem() {
044: super ();
045: }
046:
047: /**
048: * Creates a compound contribution item with the given (optional) id.
049: *
050: * @param id the contribution item identifier, or <code>null</code>
051: */
052: protected CompoundContributionItem(String id) {
053: super (id);
054: }
055:
056: /* (non-Javadoc)
057: * @see org.eclipse.jface.action.ContributionItem#fill(org.eclipse.swt.widgets.Menu, int)
058: */
059: public void fill(Menu menu, int index) {
060: if (index == -1) {
061: index = menu.getItemCount();
062: }
063: if (!dirty && menu.getParentItem() != null) {
064: // insert a dummy item so that the parent item is not disabled
065: new MenuItem(menu, SWT.NONE, index);
066: return;
067: }
068:
069: IContributionItem[] items = getContributionItemsToFill();
070: for (int i = 0; i < items.length; i++) {
071: IContributionItem item = items[i];
072: int oldItemCount = menu.getItemCount();
073: if (item.isVisible()) {
074: item.fill(menu, index);
075: }
076: int newItemCount = menu.getItemCount();
077: int numAdded = newItemCount - oldItemCount;
078: index += numAdded;
079: }
080: dirty = false;
081: }
082:
083: /**
084: * Return a list of contributions items that will replace this item in the
085: * parent manager. The list must contain new contribution items every call
086: * since the old ones will be disposed.
087: *
088: * @return an array list of items to display. Must not be <code>null</code>.
089: */
090: protected abstract IContributionItem[] getContributionItems();
091:
092: private IContributionItem[] getContributionItemsToFill() {
093: if (oldItems != null) {
094: for (int i = 0; i < oldItems.length; i++) {
095: IContributionItem oldItem = oldItems[i];
096: oldItem.dispose();
097: }
098: oldItems = null;
099: }
100: oldItems = getContributionItems();
101: return oldItems;
102: }
103:
104: /* (non-Javadoc)
105: * @see org.eclipse.jface.action.ContributionItem#isDirty()
106: */
107: public boolean isDirty() {
108: return dirty;
109: }
110:
111: /* (non-Javadoc)
112: * @see org.eclipse.jface.action.ContributionItem#isDynamic()
113: */
114: public boolean isDynamic() {
115: return true;
116: }
117:
118: /* (non-Javadoc)
119: * @see org.eclipse.jface.action.ContributionItem#setParent(org.eclipse.jface.action.IContributionManager)
120: */
121: public void setParent(IContributionManager parent) {
122: if (getParent() instanceof IMenuManager) {
123: IMenuManager menuMgr = (IMenuManager) getParent();
124: menuMgr.removeMenuListener(menuListener);
125: }
126: if (parent instanceof IMenuManager) {
127: IMenuManager menuMgr = (IMenuManager) parent;
128: menuMgr.addMenuListener(menuListener);
129: }
130: super.setParent(parent);
131: }
132: }
|