[568293] Make CDO Explorer's "Show In" sub menu extensible
https://bugs.eclipse.org/bugs/show_bug.cgi?id=568293
diff --git a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/actions/ShowInActionProvider.java b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/actions/ShowInActionProvider.java
index 45b6994..971d7a1 100644
--- a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/actions/ShowInActionProvider.java
+++ b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/actions/ShowInActionProvider.java
@@ -41,11 +41,13 @@
import org.eclipse.net4j.util.container.IManagedContainer;
import org.eclipse.net4j.util.container.IPluginContainer;
import org.eclipse.net4j.util.io.IOUtil;
+import org.eclipse.net4j.util.ui.MenuFiller;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;
@@ -83,7 +85,7 @@
public static final String HISTORY_VIEW_ID = "org.eclipse.team.ui.GenericHistoryView";
- private static final String ID = ShowInActionProvider.class.getName();
+ public static final String ID = ShowInActionProvider.class.getName();
private static final boolean PROPERTIES_SUPPORT_AVAILABLE = Support.PROPERTIES.isAvailable();
@@ -236,7 +238,13 @@
filled = true;
}
- return filled;
+ menu.add(new Separator(ICommonMenuConstants.GROUP_ADDITIONS));
+
+ boolean[] finalFilled = { filled };
+ IPluginContainer.INSTANCE.forEachElement(MenuFiller.Factory.PRODUCT_GROUP, MenuFiller.class,
+ filler -> finalFilled[0] |= filler.fillMenu(page, viewer, menu, selectedElement));
+
+ return finalFilled[0];
}
private static boolean addAction(IMenuManager subMenu, Object selectedElement, ShowInViewAction action)
@@ -425,7 +433,7 @@
/**
* @author Eike Stepper
*/
- private static class ShowInViewAction extends Action
+ public static class ShowInViewAction extends Action
{
private final IWorkbenchPage page;
@@ -499,7 +507,7 @@
/**
* @author Eike Stepper
*/
- private static final class ShowInProjectExplorerAction extends ShowInViewAction
+ public static final class ShowInProjectExplorerAction extends ShowInViewAction
{
private final CDOCheckout[] checkouts;
@@ -523,7 +531,7 @@
/**
* @author Eike Stepper
*/
- private static final class ShowInSessionsViewAction extends ShowInViewAction
+ public static final class ShowInSessionsViewAction extends ShowInViewAction
{
private final CDORepository repository;
@@ -622,7 +630,7 @@
/**
* @author Eike Stepper
*/
- private static final class ShowInSystemExplorerAction extends Action
+ public static final class ShowInSystemExplorerAction extends Action
{
private final File folder;
diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/MenuFiller.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/MenuFiller.java
new file mode 100644
index 0000000..0ec23b8
--- /dev/null
+++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/MenuFiller.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2020 Eike Stepper (Loehne, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.net4j.util.ui;
+
+import org.eclipse.net4j.util.factory.ProductCreationException;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.ui.IWorkbenchPage;
+
+/**
+ * @author Eike Stepper
+ * @since 3.9
+ */
+public interface MenuFiller
+{
+ public boolean fillMenu(IWorkbenchPage page, StructuredViewer viewer, IMenuManager menu, Object selectedElement);
+
+ /**
+ * @author Eike Stepper
+ */
+ public static abstract class Factory extends org.eclipse.net4j.util.factory.Factory
+ {
+ public static final String PRODUCT_GROUP = "org.eclipse.net4j.util.ui.menuFillers";
+
+ public Factory(String type)
+ {
+ super(PRODUCT_GROUP, type);
+ }
+
+ @Override
+ public abstract MenuFiller create(String description) throws ProductCreationException;
+ }
+}
diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/views/ContainerView.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/views/ContainerView.java
index f63347c..f7f3e3a 100644
--- a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/views/ContainerView.java
+++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/views/ContainerView.java
@@ -360,25 +360,18 @@
protected void hookDoubleClick()
{
- viewer.addDoubleClickListener(event -> {
- ITreeSelection selection = (ITreeSelection)viewer.getSelection();
- Object object = selection.getFirstElement();
- doubleClicked(object);
- });
+ viewer.addDoubleClickListener(e -> doubleClicked(((ITreeSelection)viewer.getSelection()).getFirstElement()));
}
protected void hookContextMenu()
{
- MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
- menuMgr.setRemoveAllWhenShown(true);
- menuMgr.addMenuListener(manager -> {
- ITreeSelection selection = (ITreeSelection)viewer.getSelection();
- fillContextMenu(manager, selection);
- });
+ MenuManager manager = new MenuManager("#PopupMenu"); //$NON-NLS-1$
+ manager.setRemoveAllWhenShown(true);
+ manager.addMenuListener(m -> fillContextMenu(m, (ITreeSelection)viewer.getSelection()));
- Menu menu = menuMgr.createContextMenu(viewer.getControl());
+ Menu menu = manager.createContextMenu(viewer.getControl());
viewer.getControl().setMenu(menu);
- getSite().registerContextMenu(menuMgr, viewer);
+ getSite().registerContextMenu(manager, viewer);
}
protected void contributeToActionBars()
@@ -406,10 +399,28 @@
/**
* @since 3.5
+ * @deprecated As of 3.9 use {@link #addMenuGroupAdditions(IContributionManager)}.
*/
+ @Deprecated
protected void addSeparator(IContributionManager manager)
{
- manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ addMenuGroupAdditions(manager);
+ }
+
+ /**
+ * @since 3.9
+ */
+ protected void addMenuGroupAdditions(IContributionManager manager)
+ {
+ addMenuGroup(manager, IWorkbenchActionConstants.MB_ADDITIONS);
+ }
+
+ /**
+ * @since 3.9
+ */
+ protected void addMenuGroup(IContributionManager manager, String groupName)
+ {
+ manager.add(new Separator(groupName));
}
/**
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/IManagedContainer.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/IManagedContainer.java
index 18f3300..a7c1d5f 100644
--- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/IManagedContainer.java
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/IManagedContainer.java
@@ -21,6 +21,8 @@
import java.io.OutputStream;
import java.util.List;
import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Function;
/**
* A {@link IContainer container} that populates itself by means of element {@link #getFactoryRegistry() factories} and
@@ -82,6 +84,21 @@
public Object removeElement(String productGroup, String factoryType, String description);
+ /**
+ * @since 3.13
+ */
+ public <T> void forEachElement(String productGroup, Class<T> productType, Function<String, String> descriptionProvider, Consumer<T> consumer);
+
+ /**
+ * @since 3.13
+ */
+ public <T> void forEachElement(String productGroup, Class<T> productType, String description, Consumer<T> consumer);
+
+ /**
+ * @since 3.13
+ */
+ public <T> void forEachElement(String productGroup, Class<T> productType, Consumer<T> consumer);
+
public void clearElements();
public void loadElements(InputStream stream) throws IOException, FactoryNotFoundException, ProductCreationException;
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/ManagedContainer.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/ManagedContainer.java
index 2dc7b54..ff22a2a 100644
--- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/ManagedContainer.java
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/ManagedContainer.java
@@ -44,6 +44,8 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Function;
/**
* A default implementation of a {@link IManagedContainer managed container}.
@@ -461,6 +463,42 @@
}
@Override
+ public <T> void forEachElement(String productGroup, Class<T> productType, Function<String, String> descriptionProvider, Consumer<T> consumer)
+ {
+ for (String type : getFactoryTypes(productGroup))
+ {
+ String description = descriptionProvider == null ? null : descriptionProvider.apply(type);
+
+ try
+ {
+ @SuppressWarnings("unchecked")
+ T element = (T)getElement(productGroup, type, description);
+ consumer.accept(element);
+ }
+ catch (FactoryNotFoundException ex)
+ {
+ // Should not happen.
+ }
+ catch (ProductCreationException ex)
+ {
+ OM.LOG.error(ex);
+ }
+ }
+ }
+
+ @Override
+ public <T> void forEachElement(String productGroup, Class<T> productType, String description, Consumer<T> consumer)
+ {
+ forEachElement(productGroup, productType, type -> description, consumer);
+ }
+
+ @Override
+ public <T> void forEachElement(String productGroup, Class<T> productType, Consumer<T> consumer)
+ {
+ forEachElement(productGroup, productType, type -> null, consumer);
+ }
+
+ @Override
public void clearElements()
{
checkActive();