Bug 365903 - [Compatibility] Programmatic Contribution Factories not
supported
Add support for programmatic factories for toolbars
diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ToolBarContributionRecord.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ToolBarContributionRecord.java
index 3642078..75ffd53 100644
--- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ToolBarContributionRecord.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ToolBarContributionRecord.java
@@ -12,8 +12,12 @@
package org.eclipse.e4.ui.workbench.renderers.swt;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
+import org.eclipse.e4.core.contexts.EclipseContextFactory;
+import org.eclipse.e4.core.contexts.IContextFunction;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.internal.workbench.ContributionsAnalyzer;
import org.eclipse.e4.ui.model.application.ui.MCoreExpression;
@@ -28,12 +32,17 @@
import org.eclipse.jface.action.ToolBarManager;
public class ToolBarContributionRecord {
+ public static final String FACTORY = "ToolBarContributionFactory"; //$NON-NLS-1$
+ static final String STATIC_CONTEXT = "ToolBarContributionFactoryContext"; //$NON-NLS-1$
+
MToolBar toolbarModel;
MToolBarContribution toolbarContribution;
ArrayList<MToolBarElement> generatedElements = new ArrayList<MToolBarElement>();
HashSet<MToolBarElement> sharedElements = new HashSet<MToolBarElement>();
ToolBarManagerRenderer renderer;
boolean isVisible = true;
+ private IEclipseContext infoContext;
+ private Runnable factoryDispose;
public ToolBarContributionRecord(MToolBar model,
MToolBarContribution contribution, ToolBarManagerRenderer renderer) {
@@ -128,9 +137,18 @@
return false;
}
- for (MToolBarElement item : toolbarContribution.getChildren()) {
- MToolBarElement copy = (MToolBarElement) EcoreUtil
- .copy((EObject) item);
+ final List<MToolBarElement> copyElements;
+ if (toolbarContribution.getTransientData().get(FACTORY) != null) {
+ copyElements = mergeFactoryIntoModel();
+ } else {
+ copyElements = new ArrayList<MToolBarElement>();
+ for (MToolBarElement item : toolbarContribution.getChildren()) {
+ MToolBarElement copy = (MToolBarElement) EcoreUtil
+ .copy((EObject) item);
+ copyElements.add(copy);
+ }
+ }
+ for (MToolBarElement copy : copyElements) {
// if a visibleWhen clause is defined, the item should not be
// visible until the clause has been evaluated and returned 'true'
copy.setVisible(!anyVisibleWhen());
@@ -159,6 +177,36 @@
return true;
}
+ /**
+ * @return
+ */
+ private List<MToolBarElement> mergeFactoryIntoModel() {
+ Object obj = toolbarContribution.getTransientData().get(FACTORY);
+ if (!(obj instanceof IContextFunction)) {
+ return Collections.EMPTY_LIST;
+ }
+ IEclipseContext staticContext = getStaticContext();
+ staticContext.remove(List.class);
+ factoryDispose = (Runnable) ((IContextFunction) obj)
+ .compute(staticContext);
+ return staticContext.get(List.class);
+ }
+
+ private IEclipseContext getStaticContext() {
+ if (infoContext == null) {
+ IEclipseContext parentContext = renderer.getContext(toolbarModel);
+ if (parentContext != null) {
+ infoContext = parentContext.createChild(STATIC_CONTEXT);
+ } else {
+ infoContext = EclipseContextFactory.create(STATIC_CONTEXT);
+ }
+ ContributionsAnalyzer.populateModelInterfaces(toolbarModel,
+ infoContext, toolbarModel.getClass().getInterfaces());
+ infoContext.set(ToolBarManagerRenderer.class, renderer);
+ }
+ return infoContext;
+ }
+
MToolBarSeparator findExistingSeparator(String id) {
if (id == null) {
return null;
@@ -184,6 +232,10 @@
toolbarModel.getChildren().remove(shared);
}
}
+ if (factoryDispose != null) {
+ factoryDispose.run();
+ factoryDispose = null;
+ }
}
private static int getIndex(MElementContainer<?> model,
diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ToolBarManagerRenderer.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ToolBarManagerRenderer.java
index 114a2de..03c1ae5 100644
--- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ToolBarManagerRenderer.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ToolBarManagerRenderer.java
@@ -565,7 +565,10 @@
*/
private void modelProcessSwitch(ToolBarManager parentManager,
MToolBarElement childME) {
- if (childME instanceof MHandledToolItem) {
+ if (childME instanceof MOpaqueToolItem) {
+ MOpaqueToolItem itemModel = (MOpaqueToolItem) childME;
+ processOpaqueItem(parentManager, itemModel);
+ } else if (childME instanceof MHandledToolItem) {
MHandledToolItem itemModel = (MHandledToolItem) childME;
processHandledItem(parentManager, itemModel);
} else if (childME instanceof MDirectToolItem) {
@@ -664,6 +667,23 @@
linkModelToContribution(itemModel, ci);
}
+ void processOpaqueItem(ToolBarManager parentManager,
+ MOpaqueToolItem itemModel) {
+ IContributionItem ici = getContribution(itemModel);
+ if (ici != null) {
+ return;
+ }
+ Object obj = itemModel.getOpaqueItem();
+ if (obj instanceof IContributionItem) {
+ ici = (IContributionItem) obj;
+ } else {
+ return;
+ }
+ ici.setVisible(itemModel.isVisible());
+ addToManager(parentManager, itemModel, ici);
+ linkModelToContribution(itemModel, ici);
+ }
+
/**
* @param parentManager
* @param itemModel
@@ -789,4 +809,7 @@
}
}
+ public IEclipseContext getContext(MUIElement el) {
+ return super.getContext(el);
+ }
}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/ContributionFactoryGenerator.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/ContributionFactoryGenerator.java
index a57ff4a..ac6be5c 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/ContributionFactoryGenerator.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/ContributionFactoryGenerator.java
@@ -21,9 +21,10 @@
import org.eclipse.e4.core.contexts.ContextFunction;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.model.application.ui.MCoreExpression;
+import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.impl.UiFactoryImpl;
-import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
import org.eclipse.e4.ui.model.application.ui.menu.MOpaqueMenuItem;
+import org.eclipse.e4.ui.model.application.ui.menu.MOpaqueToolItem;
import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuFactoryImpl;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.ui.internal.WorkbenchPlugin;
@@ -34,13 +35,16 @@
public class ContributionFactoryGenerator extends ContextFunction {
private AbstractContributionFactory factoryImpl;
private IConfigurationElement configElement;
+ private int type;
- public ContributionFactoryGenerator(AbstractContributionFactory factory) {
+ public ContributionFactoryGenerator(AbstractContributionFactory factory, int type) {
this.factoryImpl = factory;
+ this.type = type;
}
- public ContributionFactoryGenerator(IConfigurationElement element) {
+ public ContributionFactoryGenerator(IConfigurationElement element, int type) {
configElement = element;
+ this.type = type;
}
private AbstractContributionFactory getFactory() {
@@ -74,21 +78,21 @@
factory.createContributionItems(sl, root);
final List contributionItems = root.getItems();
final Map<IContributionItem, Expression> itemsToExpression = root.getVisibleWhen();
- List<MMenuElement> menuElements = new ArrayList<MMenuElement>();
+ List<MUIElement> menuElements = new ArrayList<MUIElement>();
for (Object obj : contributionItems) {
if (obj instanceof IContributionItem) {
IContributionItem ici = (IContributionItem) obj;
- MOpaqueMenuItem opaqueItem = MenuFactoryImpl.eINSTANCE.createOpaqueMenuItem();
- opaqueItem.setElementId(ici.getId());
- opaqueItem.setOpaqueItem(ici);
- if (itemsToExpression.containsKey(ici)) {
- final Expression ex = itemsToExpression.get(ici);
- MCoreExpression exp = UiFactoryImpl.eINSTANCE.createCoreExpression();
- exp.setCoreExpressionId("programmatic." + ici.getId()); //$NON-NLS-1$
- exp.setCoreExpression(ex);
- opaqueItem.setVisibleWhen(exp);
+ MUIElement opaqueItem = createUIElement(ici);
+ if (opaqueItem != null) {
+ if (itemsToExpression.containsKey(ici)) {
+ final Expression ex = itemsToExpression.get(ici);
+ MCoreExpression exp = UiFactoryImpl.eINSTANCE.createCoreExpression();
+ exp.setCoreExpressionId("programmatic." + ici.getId()); //$NON-NLS-1$
+ exp.setCoreExpression(ex);
+ opaqueItem.setVisibleWhen(exp);
+ }
+ menuElements.add(opaqueItem);
}
- menuElements.add(opaqueItem);
}
}
context.set(List.class, menuElements);
@@ -101,4 +105,27 @@
};
}
+ private MUIElement createUIElement(IContributionItem ici) {
+ switch (type) {
+ case 0:
+ return createMenuItem(ici);
+ case 1:
+ return createToolItem(ici);
+ }
+ return null;
+ }
+
+ private MUIElement createMenuItem(IContributionItem ici) {
+ MOpaqueMenuItem opaqueItem = MenuFactoryImpl.eINSTANCE.createOpaqueMenuItem();
+ opaqueItem.setElementId(ici.getId());
+ opaqueItem.setOpaqueItem(ici);
+ return opaqueItem;
+ }
+
+ private MUIElement createToolItem(IContributionItem ici) {
+ MOpaqueToolItem opaqueItem = MenuFactoryImpl.eINSTANCE.createOpaqueToolItem();
+ opaqueItem.setElementId(ici.getId());
+ opaqueItem.setOpaqueItem(ici);
+ return opaqueItem;
+ }
}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/MenuAdditionCacheEntry.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/MenuAdditionCacheEntry.java
index 4174498..4a8a494 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/MenuAdditionCacheEntry.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/MenuAdditionCacheEntry.java
@@ -42,17 +42,17 @@
import org.eclipse.ui.internal.services.ServiceLocator;
public class MenuAdditionCacheEntry {
- private final static String MAIN_TOOLBAR = "org.eclipse.ui.main.toolbar"; //$NON-NLS-1$
+ final static String MAIN_TOOLBAR = "org.eclipse.ui.main.toolbar"; //$NON-NLS-1$
- private final static String TRIM_COMMAND1 = "org.eclipse.ui.trim.command1"; //$NON-NLS-1$
+ final static String TRIM_COMMAND1 = "org.eclipse.ui.trim.command1"; //$NON-NLS-1$
- private final static String TRIM_COMMAND2 = "org.eclipse.ui.trim.command2"; //$NON-NLS-1$
+ final static String TRIM_COMMAND2 = "org.eclipse.ui.trim.command2"; //$NON-NLS-1$
- private final static String TRIM_VERTICAL1 = "org.eclipse.ui.trim.vertical1"; //$NON-NLS-1$
+ final static String TRIM_VERTICAL1 = "org.eclipse.ui.trim.vertical1"; //$NON-NLS-1$
- private final static String TRIM_VERTICAL2 = "org.eclipse.ui.trim.vertical2"; //$NON-NLS-1$
+ final static String TRIM_VERTICAL2 = "org.eclipse.ui.trim.vertical2"; //$NON-NLS-1$
- private final static String TRIM_STATUS = "org.eclipse.ui.trim.status"; //$NON-NLS-1$
+ final static String TRIM_STATUS = "org.eclipse.ui.trim.status"; //$NON-NLS-1$
private MApplication application;
// private IEclipseContext appContext;
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/MenuFactoryGenerator.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/MenuFactoryGenerator.java
index c31fe1c..78121f8 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/MenuFactoryGenerator.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/MenuFactoryGenerator.java
@@ -22,6 +22,7 @@
import org.eclipse.e4.ui.model.application.ui.menu.MTrimContribution;
import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuFactoryImpl;
import org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord;
+import org.eclipse.e4.ui.workbench.renderers.swt.ToolBarContributionRecord;
/**
* @since 3.102.0
@@ -41,9 +42,32 @@
this.location = new MenuLocationURI(attribute);
}
+ private boolean inToolbar() {
+ return location.getScheme().startsWith("toolbar"); //$NON-NLS-1$
+ }
+
public void mergeIntoModel(ArrayList<MMenuContribution> menuContributions,
ArrayList<MToolBarContribution> toolBarContributions,
ArrayList<MTrimContribution> trimContributions) {
+ if (inToolbar()) {
+ String path = location.getPath();
+ if (path.equals(MenuAdditionCacheEntry.MAIN_TOOLBAR)
+ || path.equals(MenuAdditionCacheEntry.TRIM_COMMAND1)
+ || path.equals(MenuAdditionCacheEntry.TRIM_COMMAND2)
+ || path.equals(MenuAdditionCacheEntry.TRIM_VERTICAL1)
+ || path.equals(MenuAdditionCacheEntry.TRIM_VERTICAL2)
+ || path.equals(MenuAdditionCacheEntry.TRIM_STATUS)) {
+ // processTrimChildren(trimContributions, toolBarContributions,
+ // configElement);
+ } else {
+ String query = location.getQuery();
+ if (query == null || query.length() == 0) {
+ query = "after=additions"; //$NON-NLS-1$
+ }
+ processToolbarChildren(toolBarContributions, configElement, path, query);
+ }
+ return;
+ }
MMenuContribution menuContribution = MenuFactoryImpl.eINSTANCE.createMenuContribution();
String idContrib = MenuHelper.getId(configElement);
if (idContrib != null && idContrib.length() > 0) {
@@ -66,8 +90,26 @@
}
menuContribution.getTags().add(filter);
menuContribution.setVisibleWhen(MenuHelper.getVisibleWhen(configElement));
- ContextFunction generator = new ContributionFactoryGenerator(configElement);
+ ContextFunction generator = new ContributionFactoryGenerator(configElement, 0);
menuContribution.getTransientData().put(ContributionRecord.FACTORY, generator);
menuContributions.add(menuContribution);
}
+
+ private void processToolbarChildren(ArrayList<MToolBarContribution> contributions,
+ IConfigurationElement toolbar, String parentId, String position) {
+ MToolBarContribution toolBarContribution = MenuFactoryImpl.eINSTANCE
+ .createToolBarContribution();
+ String idContrib = MenuHelper.getId(toolbar);
+ if (idContrib != null && idContrib.length() > 0) {
+ toolBarContribution.setElementId(idContrib);
+ }
+ toolBarContribution.setParentId(parentId);
+ toolBarContribution.setPositionInParent(position);
+ toolBarContribution.getTags().add("scheme:" + location.getScheme()); //$NON-NLS-1$
+
+ ContextFunction generator = new ContributionFactoryGenerator(configElement, 1);
+ toolBarContribution.getTransientData().put(ToolBarContributionRecord.FACTORY, generator);
+
+ contributions.add(toolBarContribution);
+ }
}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/WorkbenchMenuService.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/WorkbenchMenuService.java
index cfe9096..b065fef 100755
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/WorkbenchMenuService.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/WorkbenchMenuService.java
@@ -21,9 +21,11 @@
import org.eclipse.e4.ui.internal.workbench.ContributionsAnalyzer;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.menu.MMenuContribution;
+import org.eclipse.e4.ui.model.application.ui.menu.MToolBarContribution;
import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuFactoryImpl;
import org.eclipse.e4.ui.workbench.modeling.ExpressionContext;
import org.eclipse.e4.ui.workbench.renderers.swt.ContributionRecord;
+import org.eclipse.e4.ui.workbench.renderers.swt.ToolBarContributionRecord;
import org.eclipse.jface.action.ContributionManager;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.ui.ISourceProvider;
@@ -42,7 +44,7 @@
// private ServiceLocator serviceLocator;
private ExpressionContext legacyContext;
private MenuPersistence persistence;
- private Map<AbstractContributionFactory, MMenuContribution> factoriesToContributions = new HashMap<AbstractContributionFactory, MMenuContribution>();
+ private Map<AbstractContributionFactory, Object> factoriesToContributions = new HashMap<AbstractContributionFactory, Object>();
/**
* @param serviceLocator
@@ -78,13 +80,37 @@
persistence.dispose();
}
+ private boolean inToolbar(MenuLocationURI location) {
+ return location.getScheme().startsWith("toolbar"); //$NON-NLS-1$
+ }
+
/* (non-Javadoc)
* @see org.eclipse.ui.menus.IMenuService#addContributionFactory(org.eclipse.ui.menus.AbstractContributionFactory)
*/
public void addContributionFactory(final AbstractContributionFactory factory) {
+ MenuLocationURI location = new MenuLocationURI(factory.getLocation());
+
+ if (inToolbar(location)) {
+ String path = location.getPath();
+ if (path.equals(MenuAdditionCacheEntry.MAIN_TOOLBAR)
+ || path.equals(MenuAdditionCacheEntry.TRIM_COMMAND1)
+ || path.equals(MenuAdditionCacheEntry.TRIM_COMMAND2)
+ || path.equals(MenuAdditionCacheEntry.TRIM_VERTICAL1)
+ || path.equals(MenuAdditionCacheEntry.TRIM_VERTICAL2)
+ || path.equals(MenuAdditionCacheEntry.TRIM_STATUS)) {
+ // processTrimChildren(trimContributions, toolBarContributions,
+ // configElement);
+ } else {
+ String query = location.getQuery();
+ if (query == null || query.length() == 0) {
+ query = "after=additions"; //$NON-NLS-1$
+ }
+ processToolbarChildren(factory, location, path, query);
+ }
+ return;
+ }
MMenuContribution menuContribution = MenuFactoryImpl.eINSTANCE.createMenuContribution();
menuContribution.setElementId(factory.getNamespace() + ":" + factory.hashCode()); //$NON-NLS-1$
- MenuLocationURI location = new MenuLocationURI(factory.getLocation());
if ("org.eclipse.ui.popup.any".equals(location.getPath())) { //$NON-NLS-1$
menuContribution.setParentId("popup"); //$NON-NLS-1$
@@ -102,21 +128,41 @@
filter = ContributionsAnalyzer.MC_POPUP;
}
menuContribution.getTags().add(filter);
- ContextFunction generator = new ContributionFactoryGenerator(factory);
+ ContextFunction generator = new ContributionFactoryGenerator(factory, 0);
menuContribution.getTransientData().put(ContributionRecord.FACTORY, generator);
factoriesToContributions.put(factory, menuContribution);
MApplication app = e4Context.get(MApplication.class);
app.getMenuContributions().add(menuContribution);
}
+ private void processToolbarChildren(AbstractContributionFactory factory,
+ MenuLocationURI location, String parentId, String position) {
+ MToolBarContribution toolBarContribution = MenuFactoryImpl.eINSTANCE
+ .createToolBarContribution();
+ toolBarContribution.setElementId(factory.getNamespace() + ":" + factory.hashCode()); //$NON-NLS-1$
+ toolBarContribution.setParentId(parentId);
+ toolBarContribution.setPositionInParent(position);
+ toolBarContribution.getTags().add("scheme:" + location.getScheme()); //$NON-NLS-1$
+
+ ContextFunction generator = new ContributionFactoryGenerator(factory, 1);
+ toolBarContribution.getTransientData().put(ToolBarContributionRecord.FACTORY, generator);
+ factoriesToContributions.put(factory, toolBarContribution);
+ MApplication app = e4Context.get(MApplication.class);
+ app.getToolBarContributions().add(toolBarContribution);
+ }
+
/* (non-Javadoc)
* @see org.eclipse.ui.menus.IMenuService#removeContributionFactory(org.eclipse.ui.menus.AbstractContributionFactory)
*/
public void removeContributionFactory(AbstractContributionFactory factory) {
- MMenuContribution menuContribution;
- if ((menuContribution = factoriesToContributions.remove(factory)) != null) {
+ Object contribution;
+ if ((contribution = factoriesToContributions.remove(factory)) != null) {
MApplication app = e4Context.get(MApplication.class);
- app.getMenuContributions().remove(menuContribution);
+ if (contribution instanceof MMenuContribution) {
+ app.getMenuContributions().remove(contribution);
+ } else if (contribution instanceof MToolBarContribution) {
+ app.getToolBarContributions().remove(contribution);
+ }
}
}