/** * Incrementally builds the menu from the contribution items. This method leaves out double * separators and separators in the first or last position. * * @param force <code>true</code> means update even if not dirty, and <code>false</code> for * normal incremental updating * @param recursive <code>true</code> means recursively update all submenus, and <code>false * </code> means just this menu */ protected void update(boolean force, boolean recursive) { if (isDirty() || force) { if (menuExist()) { // clean contains all active items without double separators IContributionItem[] items = getItems(); List clean = new ArrayList(items.length); IContributionItem separator = null; for (int i = 0; i < items.length; ++i) { IContributionItem ci = items[i]; if (!isChildVisible(ci)) { continue; } if (ci.isSeparator()) { // delay creation until necessary // (handles both adjacent separators, and separator at end) separator = ci; } else { if (separator != null) { if (clean.size() > 0) { clean.add(separator); } separator = null; } clean.add(ci); } } // remove obsolete (removed or non active) Item[] mi = getMenuItems(); for (int i = 0; i < mi.length; i++) { Object data = mi[i].getData(); if (data == null || !clean.contains(data)) { mi[i].dispose(); } else if (data instanceof IContributionItem && ((IContributionItem) data).isDynamic() && ((IContributionItem) data).isDirty()) { mi[i].dispose(); } } // add new mi = getMenuItems(); int srcIx = 0; int destIx = 0; for (Iterator e = clean.iterator(); e.hasNext(); ) { IContributionItem src = (IContributionItem) e.next(); IContributionItem dest; // get corresponding item in SWT widget if (srcIx < mi.length) { dest = (IContributionItem) mi[srcIx].getData(); } else { dest = null; } if (dest != null && src.equals(dest)) { srcIx++; destIx++; } else if (dest != null && dest.isSeparator() && src.isSeparator()) { mi[srcIx].setData(src); srcIx++; destIx++; } else { int start = getMenuItemCount(); doItemFill(src, destIx); int newItems = getMenuItemCount() - start; for (int i = 0; i < newItems; i++) { Item item = getMenuItem(destIx++); item.setData(src); } } // May be we can optimize this call. If the menu has just // been created via the call src.fill(fMenuBar, destIx) then // the menu has already been updated with update(true) // (see MenuManager). So if force is true we do it again. But // we can't set force to false since then information for the // sub sub menus is lost. if (recursive) { IContributionItem item = src; if (item instanceof SubContributionItem) { item = ((SubContributionItem) item).getInnerItem(); } if (item instanceof IMenuManager) { ((IMenuManager) item).updateAll(force); } } } // remove any old menu items not accounted for for (; srcIx < mi.length; srcIx++) { mi[srcIx].dispose(); } setDirty(false); } } else { // I am not dirty. Check if I must recursivly walk down the hierarchy. if (recursive) { IContributionItem[] items = getItems(); for (int i = 0; i < items.length; ++i) { IContributionItem ci = items[i]; if (ci instanceof IMenuManager) { IMenuManager mm = (IMenuManager) ci; if (isChildVisible(mm)) { mm.updateAll(force); } } } } } updateMenuItem(); }
/* (non-Javadoc) * @see org.eclipse.jface.action.IContributionItem#update() */ public void update() { updateMenuItem(); }