public Object createWidget(final MUIElement element, Object parent) {
    if (!(element instanceof MMenu)) return null;

    final MMenu menuModel = (MMenu) element;

    Menu newMenu = null;
    if (parent instanceof Decorations) {
      MUIElement container = (MUIElement) ((EObject) element).eContainer();
      if (container instanceof MWindow) {
        newMenu = new Menu((Decorations) parent, SWT.BAR);
        newMenu.addDisposeListener(
            new DisposeListener() {
              public void widgetDisposed(DisposeEvent e) {
                cleanUp(menuModel);
              }
            });
      } else {
        newMenu = new Menu((Decorations) parent, SWT.POP_UP);
      }
    } else if (parent instanceof Menu) {
      int addIndex = calcVisibleIndex(menuModel);
      MenuItem newItem = new MenuItem((Menu) parent, SWT.CASCADE, addIndex);
      setItemText(menuModel, newItem);
      newItem.setImage(getImage(menuModel));
      newItem.setEnabled(menuModel.isEnabled());
      return newItem;
    } else if (parent instanceof Control) {
      newMenu = new Menu((Control) parent);
    }

    return newMenu;
  }
 private void createModelFor(String id) {
   if (id == null) {
     id = getClass().getName() + '.' + System.identityHashCode(this);
   }
   menuModel = null;
   for (MMenu item : modelPart.getMenus()) {
     if (id.equals(item.getElementId())
         && item instanceof MPopupMenu
         && item.getTags().contains(ContributionsAnalyzer.MC_POPUP)) {
       menuModel = (MPopupMenu) item;
       break;
     }
   }
   if (menuModel == null) {
     menuModel = MenuFactoryImpl.eINSTANCE.createPopupMenu();
     menuModel.setElementId(id);
     menuModel.getTags().add(ContributionsAnalyzer.MC_POPUP);
     modelPart.getMenus().add(menuModel);
   }
   IRendererFactory factory = modelPart.getContext().get(IRendererFactory.class);
   AbstractPartRenderer obj = factory.getRenderer(menuModel, null);
   if (obj instanceof MenuManagerRenderer) {
     ((MenuManagerRenderer) obj).linkModelToManager(menuModel, menu);
   }
   registerE4Support();
   cleanUpContributionCache();
 }
  public void testCreateMenu() {
    final MWindow window = createWindowWithOneViewAndMenu();
    wb = new E4Workbench(window, appContext);

    Widget topWidget = (Widget) window.getWidget();
    assertTrue(topWidget instanceof Shell);
    Shell shell = (Shell) topWidget;
    final Menu menuBar = shell.getMenuBar();
    assertNotNull(menuBar);
    assertEquals(1, menuBar.getItemCount());
    final MenuItem fileItem = menuBar.getItem(0);
    assertEquals("File", fileItem.getText());
    final Menu fileMenu = fileItem.getMenu();
    fileMenu.notifyListeners(SWT.Show, null);
    assertEquals(2, fileMenu.getItemCount());
    fileMenu.notifyListeners(SWT.Hide, null);

    MMenu mainMenu = window.getMainMenu();
    MMenu modelFileMenu = (MMenu) mainMenu.getChildren().get(0);
    final MMenuItem item2Model = (MMenuItem) modelFileMenu.getChildren().get(0);
    item2Model.setToBeRendered(false);
    fileMenu.notifyListeners(SWT.Show, null);
    assertEquals(1, fileMenu.getItemCount());
    fileMenu.notifyListeners(SWT.Hide, null);

    item2Model.setToBeRendered(true);
    fileMenu.notifyListeners(SWT.Show, null);
    assertEquals(2, fileMenu.getItemCount());
    fileMenu.notifyListeners(SWT.Hide, null);
  }
 public static boolean processAddition(
     final MMenu menuModel,
     final ArrayList<MMenuElement> menuContributionsToRemove,
     MMenuContribution menuContribution,
     final HashSet<String> existingMenuIds,
     HashSet<String> existingSeparatorNames) {
   int idx = getIndex(menuModel, menuContribution.getPositionInParent());
   if (idx == -1) {
     return false;
   }
   for (MMenuElement item : menuContribution.getChildren()) {
     if (item instanceof MMenu && existingMenuIds.contains(item.getElementId())) {
       // skip this, it's already there
       continue;
     } else if (item instanceof MMenuSeparator
         && existingSeparatorNames.contains(item.getElementId())) {
       // skip this, it's already there
       continue;
     }
     MMenuElement copy = (MMenuElement) EcoreUtil.copy((EObject) item);
     if (DEBUG) {
       trace("addMenuContribution " + copy, menuModel.getWidget(), menuModel); // $NON-NLS-1$
     }
     menuContributionsToRemove.add(copy);
     menuModel.getChildren().add(idx++, copy);
     if (copy instanceof MMenu && copy.getElementId() != null) {
       existingMenuIds.add(copy.getElementId());
     } else if (copy instanceof MMenuSeparator && copy.getElementId() != null) {
       existingSeparatorNames.add(copy.getElementId());
     }
   }
   return true;
 }
 private MHandledMenuItem findMenuItem(final String inItemID, final MMenu inMenu) {
   inMenu.getChildren();
   for (final MMenuElement lItem : inMenu.getChildren()) {
     if (inItemID.equals(lItem.getElementId())) {
       return (MHandledMenuItem) lItem;
     }
   }
   return null;
 }
 private MMenu getPopupMenu(final MApplication inApplication, final EModelService inModel) {
   if (popupStyles == null) {
     final MPart lPart = (MPart) inModel.find(RelationsConstants.PART_INSPECTOR, inApplication);
     for (final MMenu lMenu : lPart.getMenus()) {
       if (RelationsConstants.POPUP_INSPECTOR.equals(lMenu.getElementId())) {
         popupStyles = lMenu;
         break;
       }
     }
   }
   return popupStyles;
 }
 public void handleEvent(Event event) {
   Object element = event.getProperty(UIEvents.EventTags.ELEMENT);
   String attName = (String) event.getProperty(UIEvents.EventTags.ATTNAME);
   if (element instanceof MMenuItem) {
     MMenuItem itemModel = (MMenuItem) element;
     if (UIEvents.UIElement.TOBERENDERED.equals(attName)) {
       Object obj = itemModel.getParent();
       if (!(obj instanceof MMenu)) {
         return;
       }
       MenuManager parent = getManager((MMenu) obj);
       if (itemModel.isToBeRendered()) {
         if (parent != null) {
           modelProcessSwitch(parent, itemModel);
         }
       } else {
         IContributionItem ici = getContribution(itemModel);
         clearModelToContribution(itemModel, ici);
         if (ici != null && parent != null) {
           parent.remove(ici);
         }
         if (ici != null) {
           ici.dispose();
         }
       }
     }
   }
   if (UIEvents.UIElement.VISIBLE.equals(attName)) {
     if (element instanceof MMenu) {
       MMenu menuModel = (MMenu) element;
       MenuManager manager = getManager(menuModel);
       if (manager == null) {
         return;
       }
       manager.setVisible(menuModel.isVisible());
       if (manager.getParent() != null) {
         manager.getParent().markDirty();
       }
     } else if (element instanceof MMenuElement) {
       MMenuElement itemModel = (MMenuElement) element;
       Object obj = getContribution(itemModel);
       if (!(obj instanceof ContributionItem)) {
         return;
       }
       ContributionItem item = (ContributionItem) obj;
       item.setVisible(itemModel.isVisible());
       if (item.getParent() != null) {
         item.getParent().markDirty();
       }
     }
   }
 }
  @SuppressWarnings("restriction")
  @Execute
  public void execute(
      MApplication app, EModelService service, IExtensionRegistry registery, IThemeManager mgr) {

    // sanity check
    if (menu == null) {
      return;
    }

    List<String> tags = app.getTags();
    for (String tag : tags) {
      if (PROCESSOR_ID.equals(tag)) {
        return; // already processed
      }
    }

    tags.add(PROCESSOR_ID);

    IThemeEngine engine = mgr.getEngineForDisplay(Display.getCurrent());

    List<ITheme> themes = engine.getThemes();

    MCommand switchThemeCommand = ThemeHelper.findCommand(app);

    // no themes or command, stop processing
    if (themes.size() <= 0 || switchThemeCommand == null) {
      return;
    }

    themesMenu = service.createModelElement(MMenu.class);
    themesMenu.setLabel("%switchThemeMenu"); // $NON-NLS-1$
    themesMenu.setContributorURI(BUNDLE_ID);

    for (ITheme theme : themes) {
      if (!theme.getId().startsWith("org.eclipse.e4.demo.contacts.")) {
        return;
      }
      MParameter parameter = service.createModelElement(MParameter.class);
      parameter.setName("contacts.commands.switchtheme.themeid"); // $NON-NLS-1$
      parameter.setValue(theme.getId());
      String iconURI = ThemeHelper.getCSSUri(theme.getId(), registery);
      if (iconURI != null) {
        iconURI = iconURI.replace(".css", ".png");
      }
      processTheme(theme.getLabel(), switchThemeCommand, parameter, iconURI, service);
    }
    menu.getChildren().add(themesMenu);
  }
 /**
  * Unlink all contribution items from the given model menu.
  *
  * @param renderer the renderer that is holding the links
  * @param menu the model menu whose children should have its items unlinked from their
  *     corresponding contribution items
  */
 private void unlink(MenuManagerRenderer renderer, MMenu menu) {
   for (MMenuElement menuElement : menu.getChildren()) {
     if (menuElement instanceof MOpaqueMenuItem) {
       MOpaqueMenuItem opaqueMenuItem = (MOpaqueMenuItem) menuElement;
       Object item = opaqueMenuItem.getOpaqueItem();
       if (item instanceof IContributionItem) {
         renderer.clearModelToContribution(opaqueMenuItem, (IContributionItem) item);
         opaqueMenuItem.setOpaqueItem(null);
       }
     } else if (menuElement instanceof MOpaqueMenuSeparator) {
       MOpaqueMenuSeparator opaqueMenuItem = (MOpaqueMenuSeparator) menuElement;
       Object item = opaqueMenuItem.getOpaqueItem();
       if (item instanceof IContributionItem) {
         renderer.clearModelToContribution(opaqueMenuItem, (IContributionItem) item);
         opaqueMenuItem.setOpaqueItem(null);
       }
     } else if (menuElement instanceof MMenu) {
       MMenu subMenu = (MMenu) menuElement;
       unlink(renderer, subMenu);
       MenuManager manager = renderer.getManager(subMenu);
       if (manager != null) {
         renderer.clearModelToManager(subMenu, manager);
       }
     } else {
       IContributionItem contribution = renderer.getContribution(menuElement);
       if (contribution != null) {
         renderer.clearModelToContribution(menuElement, contribution);
       }
     }
   }
 }
 private void setItemText(MMenu model, MenuItem item) {
   String text = model.getLocalizedLabel();
   if (text == null) {
     text = ""; // $NON-NLS-1$
   }
   item.setText(text);
 }
  private void showStandaloneViewMenu(
      ExecutionEvent event, MPart model, MMenu menuModel, Composite partContainer) {
    Shell shell = partContainer.getShell();
    Menu menu = (Menu) menuModel.getWidget();
    if (menu == null) {
      IPresentationEngine engine =
          (IPresentationEngine) HandlerUtil.getVariable(event, IPresentationEngine.class.getName());
      menu = (Menu) engine.createGui(menuModel, shell, model.getContext());
      if (menu != null) {
        final Menu tmpMenu = menu;
        partContainer.addDisposeListener(
            new DisposeListener() {
              public void widgetDisposed(DisposeEvent e) {
                tmpMenu.dispose();
              }
            });
      }
    }

    Display display = menu.getDisplay();
    Point location = display.map(partContainer, null, partContainer.getLocation());
    Point size = partContainer.getSize();
    menu.setLocation(location.x + size.x, location.y);
    menu.setVisible(true);

    while (!menu.isDisposed() && menu.isVisible()) {
      if (!display.readAndDispatch()) display.sleep();
    }

    if (!(menu.getData() instanceof MenuManager)) {
      menu.dispose();
    }
  }
 private String getText(MMenu menuModel) {
   String text = menuModel.getLocalizedLabel();
   if (text == null || text.length() == 0) {
     return NO_LABEL;
   }
   return text;
 }
 static boolean isFiltered(
     MMenu menuModel, MMenuContribution menuContribution, boolean includePopups) {
   if (includePopups || menuModel.getTags().contains(ContributionsAnalyzer.MC_POPUP)) {
     return !menuContribution.getTags().contains(ContributionsAnalyzer.MC_POPUP)
         && menuContribution.getTags().contains(ContributionsAnalyzer.MC_MENU);
   }
   if (menuModel.getTags().contains(ContributionsAnalyzer.MC_MENU)) {
     return !menuContribution.getTags().contains(ContributionsAnalyzer.MC_MENU)
         && menuContribution.getTags().contains(ContributionsAnalyzer.MC_POPUP);
   }
   if (!includePopups) {
     // not including popups, so filter out popup menu contributions if the menu is a regular
     // menu
     return menuContribution.getTags().contains(ContributionsAnalyzer.MC_POPUP);
   }
   return false;
 }
 @PostConstruct
 public void init() {
   itemMap = new HashMap<>();
   MMenu menu =
       (MMenu)
           modelService
               .findElements(
                   application,
                   "at.bestsolution.dart.app.menu.editorfeatures",
                   null,
                   null,
                   EModelService.ANYWHERE | EModelService.IN_MAIN_MENU)
               .get(0);
   menu.getChildren().clear();
   menu.getChildren()
       .addAll(Stream.of(Feature.values()).map(this::createFeature).collect(Collectors.toList()));
   updateFeatureSet();
 }
 /**
  * @param menuModel
  * @param isMenuBar
  * @param isPopup
  */
 public void processContributions(MMenu menuModel, boolean isMenuBar, boolean isPopup) {
   if (menuModel.getElementId() == null) {
     return;
   }
   final ArrayList<MMenuContribution> toContribute = new ArrayList<MMenuContribution>();
   ContributionsAnalyzer.XXXgatherMenuContributions(
       menuModel,
       application.getMenuContributions(),
       menuModel.getElementId(),
       toContribute,
       null,
       isPopup);
   generateContributions(menuModel, toContribute, isMenuBar);
   for (MMenuElement element : menuModel.getChildren()) {
     if (element instanceof MMenu) {
       processContributions((MMenu) element, false, isPopup);
     }
   }
 }
Exemple #16
0
  private void restorePersistedState(MApplication application, MPart part) {

    final Map<String, String> persistedState = application.getPersistedState();
    showSuppressedLines =
        toolbox.parseBoolean(persistedState.get(IPersistenceKey.TERMINAL_SUPPRESS_LINES));
    showGrblStateLines =
        toolbox.parseBoolean(persistedState.get(IPersistenceKey.TERMINAL_GRBL_STATE));
    showGcodeModeLines =
        toolbox.parseBoolean(persistedState.get(IPersistenceKey.TERMINAL_GRBL_MODES));

    // set the state of the direct menu items according to persisted state
    // find the two direct menu items
    final MToolBar toolbar = part.getToolbar();
    List<MToolBarElement> toolBarChildren = toolbar.getChildren();
    for (MToolBarElement child : toolBarChildren) {
      if (child instanceof MHandledToolItem
          && child
              .getElementId()
              .equals("de.jungierek.grblrunner.handledtoolitem.terminal.togglesuppresslines")) {
        LOG.debug(
            "restorePersistedState: child=" + child.getElementId() + " class=" + child.getClass());
        MMenu menu = ((MHandledToolItem) child).getMenu();
        if (menu != null) {
          List<MMenuElement> items = menu.getChildren();
          for (MMenuElement item : items) {
            LOG.debug(
                "restorePersistedState: item=" + item.getElementId() + "class=" + child.getClass());
            switch (item.getElementId()) {
              case "de.jungierek.grblrunner.directmenuitem.togglesuppresslines.grblstate":
                ((MMenuItem) item).setSelected(showGrblStateLines);
                break;
              case "de.jungierek.grblrunner.directmenuitem.togglesuppresslines.gcodestate":
                ((MMenuItem) item).setSelected(showGcodeModeLines);
                break;
              default:
                break;
            }
          }
        }
      }
    }
  }
 void cleanUp(MMenu menuModel) {
   ArrayList<ArrayList<MMenuElement>> lists = pendingCleanup.remove(menuModel);
   if (lists == null) {
     return;
   }
   for (ArrayList<MMenuElement> list : lists) {
     for (MMenuElement item : list) {
       menuModel.getChildren().remove(item);
     }
   }
 }
 /**
  * @param parentManager
  * @param menuModel
  */
 private void processMenu(MenuManager parentManager, MMenu menuModel) {
   MenuManager menuManager = getManager(menuModel);
   if (menuManager == null) {
     String menuText = getText(menuModel);
     ImageDescriptor desc = getImageDescriptor(menuModel);
     menuManager = new MenuManager(menuText, desc, menuModel.getElementId());
     linkModelToManager(menuModel, menuManager);
     menuManager.setVisible(menuModel.isVisible());
     addToManager(parentManager, menuModel, menuManager);
   }
   // processContributions(menuModel, false);
   List<MMenuElement> parts = menuModel.getChildren();
   if (parts != null) {
     MMenuElement[] plist = parts.toArray(new MMenuElement[parts.size()]);
     for (int i = 0; i < plist.length; i++) {
       MMenuElement childME = plist[i];
       modelProcessSwitch(menuManager, childME);
     }
   }
 }
 private void redirectHandledMenuItems(MMenu menu) {
   if (menu == null) {
     return;
   }
   for (MMenuElement elmt : menu.getChildren()) {
     if (elmt instanceof MMenu) {
       redirectHandledMenuItems((MMenu) elmt);
     } else if (elmt instanceof MMenuItem) {
       redirectHandledMenuItem((MMenuItem) elmt);
     }
   }
 }
  /*
   * (non-Javadoc)
   *
   * @see
   * org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer#processContents
   * (org.eclipse.e4.ui.model.application.ui.MElementContainer)
   */
  @Override
  public void processContents(MElementContainer<MUIElement> container) {
    if (container.getChildren().size() == 0) {
      Object obj = container.getWidget();
      if (obj instanceof MenuItem) {
        MenuItem mi = (MenuItem) obj;
        if (mi.getMenu() == null) {
          mi.setMenu(new Menu(mi));
        }
        Menu menu = mi.getMenu();
        MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
        menuItem.setText(MenuManagerRendererFilter.NUL_MENU_ITEM);
        menuItem.setEnabled(false);
      }
    }

    super.processContents(container);

    Object obj = container.getWidget();
    Object menuObj = container;
    if ((obj instanceof Menu)
        && (((Menu) obj).getStyle() & SWT.BAR) != 0
        && (menuObj instanceof MMenu)) {
      MMenu menuModel = (MMenu) menuObj;
      IEclipseContext ctx = getContext(container);
      ExpressionContext eContext = new ExpressionContext(ctx);
      ArrayList<MMenuContribution> toContribute = new ArrayList<MMenuContribution>();
      ContributionsAnalyzer.gatherMenuContributions(
          menuModel,
          application.getMenuContributions(),
          menuModel.getElementId(),
          toContribute,
          eContext,
          false);
      addMenuBarContributions(menuModel, toContribute, ctx, eContext);
    }
  }
 protected void processTheme(
     String name,
     MCommand switchCommand,
     MParameter themeId,
     String iconURI,
     EModelService service) {
   MHandledMenuItem menuItem = service.createModelElement(MHandledMenuItem.class);
   menuItem.setLabel(name);
   menuItem.setCommand(switchCommand);
   menuItem.getParameters().add(themeId);
   menuItem.setContributorURI(BUNDLE_ID);
   if (iconURI != null) {
     menuItem.setIconURI(iconURI);
   }
   themesMenu.getChildren().add(menuItem);
 }
 /**
  * Find the action with the given ID by recursively crawling the provided menu manager. If the
  * action cannot be found <code>null</code> is returned.
  *
  * @param actionId the id to search for
  * @param menu the menu to search
  * @return the action or <code>null</code>
  */
 private MMenuItem findAction(String actionId, MMenu menu) {
   if (menu == null) {
     return null;
   }
   for (MMenuElement item : menu.getChildren()) {
     if (item instanceof MMenuItem) {
       MMenuItem mmi = (MMenuItem) item;
       if (mmi.getElementId() != null && mmi.getElementId().equals(actionId)) return mmi;
       if (mmi instanceof MHandledMenuItem) {
         MHandledMenuItem mhmi = (MHandledMenuItem) mmi;
         if (mhmi.getCommand() != null && actionId.equals(mhmi.getCommand().getElementId())) {
           return mmi;
         }
       }
     } else if (item instanceof MMenu) {
       MMenuItem found = findAction(actionId, (MMenu) item);
       if (found != null) return found;
     }
   }
   return null;
 }
 public static void XXXgatherMenuContributions(
     final MMenu menuModel,
     final List<MMenuContribution> menuContributionList,
     final String id,
     final ArrayList<MMenuContribution> toContribute,
     final ExpressionContext eContext,
     boolean includePopups) {
   if (id == null || id.length() == 0) {
     return;
   }
   ArrayList<String> popupIds = new ArrayList<String>();
   if (includePopups) {
     popupIds.add(id);
     for (String tag : menuModel.getTags()) {
       if (tag.startsWith("popup:")) { // $NON-NLS-1$
         String tmp = tag.substring("popup:".length()); // $NON-NLS-1$
         if (!popupIds.contains(tmp)) {
           popupIds.add(tmp);
         }
       }
     }
   }
   for (MMenuContribution menuContribution : menuContributionList) {
     String parentID = menuContribution.getParentId();
     if (parentID == null) {
       // it doesn't make sense for this to be null, temporary workaround for bug 320790
       continue;
     }
     boolean popupTarget = includePopups && popupIds.contains(parentID);
     boolean popupAny =
         includePopups && menuModel instanceof MPopupMenu && POPUP_PARENT_ID.equals(parentID);
     boolean filtered = isFiltered(menuModel, menuContribution, includePopups);
     if (filtered
         || (!popupAny && !popupTarget && !parentID.equals(id))
         || !menuContribution.isToBeRendered()) {
       continue;
     }
     toContribute.add(menuContribution);
   }
 }
  private MWindow createWindowWithOneViewAndMenu() {
    final MWindow window = createWindowWithOneView();
    final MMenu menuBar = MenuFactoryImpl.eINSTANCE.createMenu();
    window.setMainMenu(menuBar);
    final MMenu fileMenu = MenuFactoryImpl.eINSTANCE.createMenu();
    fileMenu.setLabel("File");
    fileMenu.setElementId("file");
    menuBar.getChildren().add(fileMenu);

    final MMenuItem item1 = MenuFactoryImpl.eINSTANCE.createDirectMenuItem();
    item1.setElementId("item1");
    item1.setLabel("item1");
    fileMenu.getChildren().add(item1);
    final MMenuItem item2 = MenuFactoryImpl.eINSTANCE.createDirectMenuItem();
    item2.setElementId("item2");
    item2.setLabel("item2");
    fileMenu.getChildren().add(item2);

    return window;
  }
  /**
   * @param menuModel
   * @param toContribute
   */
  private void generateContributions(
      MMenu menuModel, ArrayList<MMenuContribution> toContribute, boolean menuBar) {
    HashSet<String> existingMenuIds = new HashSet<String>();
    HashSet<String> existingSeparatorNames = new HashSet<String>();
    for (MMenuElement child : menuModel.getChildren()) {
      String elementId = child.getElementId();
      if (child instanceof MMenu && elementId != null) {
        existingMenuIds.add(elementId);
      } else if (child instanceof MMenuSeparator && elementId != null) {
        existingSeparatorNames.add(elementId);
      }
    }

    MenuManager manager = getManager(menuModel);
    boolean done = toContribute.size() == 0;
    while (!done) {
      ArrayList<MMenuContribution> curList = new ArrayList<MMenuContribution>(toContribute);
      int retryCount = toContribute.size();
      toContribute.clear();

      for (MMenuContribution menuContribution : curList) {
        if (!processAddition(
            menuModel,
            manager,
            menuContribution,
            existingMenuIds,
            existingSeparatorNames,
            menuBar)) {
          toContribute.add(menuContribution);
        }
      }

      // We're done if the retryList is now empty (everything done) or
      // if the list hasn't changed at all (no hope)
      done = (toContribute.size() == 0) || (toContribute.size() == retryCount);
    }
  }
  public static void addMenuContributions(
      final MMenu menuModel,
      final ArrayList<MMenuContribution> toContribute,
      final ArrayList<MMenuElement> menuContributionsToRemove) {

    HashSet<String> existingMenuIds = new HashSet<String>();
    HashSet<String> existingSeparatorNames = new HashSet<String>();
    for (MMenuElement child : menuModel.getChildren()) {
      String elementId = child.getElementId();
      if (child instanceof MMenu && elementId != null) {
        existingMenuIds.add(elementId);
      } else if (child instanceof MMenuSeparator && elementId != null) {
        existingSeparatorNames.add(elementId);
      }
    }

    boolean done = toContribute.size() == 0;
    while (!done) {
      ArrayList<MMenuContribution> curList = new ArrayList<MMenuContribution>(toContribute);
      int retryCount = toContribute.size();
      toContribute.clear();

      for (MMenuContribution menuContribution : curList) {
        if (!processAddition(
            menuModel,
            menuContributionsToRemove,
            menuContribution,
            existingMenuIds,
            existingSeparatorNames)) {
          toContribute.add(menuContribution);
        }
      }
      // We're done if the retryList is now empty (everything done) or
      // if the list hasn't changed at all (no hope)
      done = (toContribute.size() == 0) || (toContribute.size() == retryCount);
    }
  }
  /**
   * @param menuManager
   * @param menuModel
   */
  public void reconcileManagerToModel(MenuManager menuManager, MMenu menuModel) {
    List<MMenuElement> modelChildren = menuModel.getChildren();

    HashSet<MOpaqueMenuItem> oldModelItems = new HashSet<MOpaqueMenuItem>();
    HashSet<MOpaqueMenu> oldMenus = new HashSet<MOpaqueMenu>();
    HashSet<MOpaqueMenuSeparator> oldSeps = new HashSet<MOpaqueMenuSeparator>();
    for (MMenuElement itemModel : modelChildren) {
      if (itemModel instanceof MOpaqueMenuSeparator) {
        oldSeps.add((MOpaqueMenuSeparator) itemModel);
      } else if (itemModel instanceof MOpaqueMenuItem) {
        oldModelItems.add((MOpaqueMenuItem) itemModel);
      } else if (itemModel instanceof MOpaqueMenu) {
        oldMenus.add((MOpaqueMenu) itemModel);
      }
    }

    IContributionItem[] items = menuManager.getItems();
    for (int src = 0, dest = 0; src < items.length; src++, dest++) {
      IContributionItem item = items[src];
      if (item instanceof MenuManager) {
        MenuManager childManager = (MenuManager) item;
        MMenu childModel = getMenuModel(childManager);
        if (childModel == null) {
          MMenu legacyModel = MenuFactoryImpl.eINSTANCE.createOpaqueMenu();
          legacyModel.setElementId(childManager.getId());
          legacyModel.setVisible(childManager.isVisible());
          linkModelToManager(legacyModel, childManager);
          modelChildren.add(dest, legacyModel);
          reconcileManagerToModel(childManager, legacyModel);
        } else {
          if (childModel instanceof MOpaqueMenu) {
            oldMenus.remove(childModel);
          }
          if (modelChildren.size() > dest) {
            if (modelChildren.get(dest) != childModel) {
              modelChildren.remove(childModel);
              modelChildren.add(dest, childModel);
            }
          } else {
            modelChildren.add(childModel);
          }
        }
      } else if (item.isSeparator() || item.isGroupMarker()) {
        MMenuElement menuElement = getMenuElement(item);
        if (menuElement == null) {
          MOpaqueMenuSeparator legacySep = MenuFactoryImpl.eINSTANCE.createOpaqueMenuSeparator();
          legacySep.setElementId(item.getId());
          legacySep.setVisible(item.isVisible());
          legacySep.setOpaqueItem(item);
          linkModelToContribution(legacySep, item);
          modelChildren.add(dest, legacySep);
        } else if (menuElement instanceof MOpaqueMenuSeparator) {
          MOpaqueMenuSeparator legacySep = (MOpaqueMenuSeparator) menuElement;
          oldSeps.remove(legacySep);
          if (modelChildren.size() > dest) {
            if (modelChildren.get(dest) != legacySep) {
              modelChildren.remove(legacySep);
              modelChildren.add(dest, legacySep);
            }
          } else {
            modelChildren.add(legacySep);
          }
        }
      } else {
        MMenuElement menuElement = getMenuElement(item);
        if (menuElement == null) {
          MOpaqueMenuItem legacyItem = MenuFactoryImpl.eINSTANCE.createOpaqueMenuItem();
          legacyItem.setElementId(item.getId());
          legacyItem.setVisible(item.isVisible());
          legacyItem.setOpaqueItem(item);
          linkModelToContribution(legacyItem, item);
          modelChildren.add(dest, legacyItem);
        } else if (menuElement instanceof MOpaqueMenuItem) {
          MOpaqueMenuItem legacyItem = (MOpaqueMenuItem) menuElement;
          oldModelItems.remove(legacyItem);
          if (modelChildren.size() > dest) {
            if (modelChildren.get(dest) != legacyItem) {
              modelChildren.remove(legacyItem);
              modelChildren.add(dest, legacyItem);
            }
          } else {
            modelChildren.add(legacyItem);
          }
        }
      }
    }
    if (!oldModelItems.isEmpty()) {
      modelChildren.removeAll(oldModelItems);
      for (MOpaqueMenuItem model : oldModelItems) {
        clearModelToContribution(model, (IContributionItem) model.getOpaqueItem());
      }
    }
    if (!oldMenus.isEmpty()) {
      modelChildren.removeAll(oldMenus);
      for (MOpaqueMenu oldMenu : oldMenus) {
        MenuManager oldManager = getManager(oldMenu);
        clearModelToManager(oldMenu, oldManager);
      }
    }
    if (!oldSeps.isEmpty()) {
      modelChildren.removeAll(oldSeps);
      for (MOpaqueMenuSeparator model : oldSeps) {
        clearModelToContribution(model, (IContributionItem) model.getOpaqueItem());
      }
    }
  }
  // this is similar in nature to:
  // org.eclipse.e4.ui.internal.workbench.ContributionsAnalyzer.addMenuContributions(MMenu,
  // ArrayList<MMenuContribution>, ArrayList<MMenuElement>)
  // the difference is it needs to add all the contributions and manage their
  // visiblility through a RAT
  private void addMenuBarContributions(
      final MMenu menuModel,
      ArrayList<MMenuContribution> toContribute,
      final IEclipseContext ctx,
      final ExpressionContext eContext) {
    HashSet<String> existingMenuIds = new HashSet<String>();
    HashSet<String> existingSeparatorNames = new HashSet<String>();
    for (MMenuElement child : menuModel.getChildren()) {
      String elementId = child.getElementId();
      if (child instanceof MMenu && elementId != null) {
        existingMenuIds.add(elementId);
      } else if (child instanceof MMenuSeparator && elementId != null) {
        existingSeparatorNames.add(elementId);
      }
    }

    boolean done = toContribute.size() == 0;
    while (!done) {
      ArrayList<MMenuContribution> curList = new ArrayList<MMenuContribution>(toContribute);
      int retryCount = toContribute.size();
      toContribute.clear();

      for (final MMenuContribution menuContribution : curList) {
        final ArrayList<MMenuElement> menuContributionsToRemove = new ArrayList<MMenuElement>();
        if (!ContributionsAnalyzer.processAddition(
            menuModel,
            menuContributionsToRemove,
            menuContribution,
            existingMenuIds,
            existingSeparatorNames)) {
          toContribute.add(menuContribution);
        } else {
          if (menuContribution.getVisibleWhen() != null) {
            ctx.runAndTrack(
                new RunAndTrack() {
                  @Override
                  public boolean changed(IEclipseContext context) {
                    if (!menuModel.isToBeRendered()
                        || !menuModel.isVisible()
                        || menuModel.getWidget() == null) {
                      return false;
                    }
                    boolean rc = ContributionsAnalyzer.isVisible(menuContribution, eContext);
                    for (MMenuElement element : menuContributionsToRemove) {
                      element.setToBeRendered(rc);
                    }
                    return true;
                  }
                });
          }
          ArrayList<ArrayList<MMenuElement>> lists = pendingCleanup.get(menuModel);
          if (lists == null) {
            lists = new ArrayList<ArrayList<MMenuElement>>();
            pendingCleanup.put(menuModel, lists);
          }
          lists.add(menuContributionsToRemove);
        }
      }
      // We're done if the retryList is now empty (everything done) or
      // if the list hasn't changed at all (no hope)
      done = (toContribute.size() == 0) || (toContribute.size() == retryCount);
    }
  }
 void removeMenuContributions(
     final MMenu menuModel, final ArrayList<MMenuElement> menuContributionsToRemove) {
   for (MMenuElement item : menuContributionsToRemove) {
     menuModel.getChildren().remove(item);
   }
 }
  /*
   * (non-Javadoc)
   *
   * @see
   * org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer#createWidget
   * (org.eclipse.e4.ui.model.application.ui.MUIElement, java.lang.Object)
   */
  @Override
  public Object createWidget(MUIElement element, Object parent) {
    if (!(element instanceof MMenu)) return null;

    final MMenu menuModel = (MMenu) element;
    Menu newMenu = null;
    MenuManager menuManager = null;
    boolean menuBar = false;

    if (parent instanceof Decorations) {
      MUIElement container = (MUIElement) ((EObject) element).eContainer();
      if (container instanceof MWindow) {
        menuManager = getManager(menuModel);
        if (menuManager == null) {
          menuManager = new MenuManager(NO_LABEL, menuModel.getElementId());
          linkModelToManager(menuModel, menuManager);
        }
        newMenu = menuManager.createMenuBar((Decorations) parent);
        ((Decorations) parent).setMenuBar(newMenu);
        newMenu.setData(menuManager);
        menuBar = true;
      } else {
        menuManager = getManager(menuModel);
        if (menuManager == null) {
          menuManager = new MenuManager(NO_LABEL, menuModel.getElementId());
          linkModelToManager(menuModel, menuManager);
        }
        newMenu = menuManager.createContextMenu((Control) parent);
        // we can't be sure this is the correct parent.
        // ((Control) parent).setMenu(newMenu);
        newMenu.setData(menuManager);
      }
    } else if (parent instanceof Menu) {
      // Object data = ((Menu) parent).getData();
      logger.debug(
          new Exception(),
          "Trying to render a sub menu " //$NON-NLS-1$
              + menuModel
              + "\n\t"
              + parent); //$NON-NLS-1$
      return null;

    } else if (parent instanceof Control) {
      menuManager = getManager(menuModel);
      if (menuManager == null) {
        menuManager = new MenuManager(NO_LABEL, menuModel.getElementId());
        linkModelToManager(menuModel, menuManager);
      }
      newMenu = menuManager.createContextMenu((Control) parent);
      // we can't be sure this is the correct parent.
      // ((Control) parent).setMenu(newMenu);
      newMenu.setData(menuManager);
    }
    if (!menuManager.getRemoveAllWhenShown()) {
      processContributions(menuModel, menuBar, menuModel instanceof MPopupMenu);
    }
    if (newMenu != null) {
      newMenu.addDisposeListener(
          new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
              cleanUp(menuModel);
            }
          });
    }
    return newMenu;
  }