diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java index 6e2fa668ec..7fa90ce7cc 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java @@ -2150,6 +2150,12 @@ public class PDEUIMessages extends NLS { public static String ProductFileWizadPage_basic; public static String Product_overview_exporting; public static String GeneralInfoSection_desc; + public static String GeneralInfoSection_BundleShape_default; + public static String GeneralInfoSection_BundleShape_dir; + public static String GeneralInfoSection_BundleShape_jar; + public static String GeneralInfoSection_BundleShape_default_tooltip; + public static String GeneralInfoSection_BundleShape_dir_tooltip; + public static String GeneralInfoSection_BundleShape_jar_tooltip; public static String ProductInfoSection_desc; public static String ProductInfoSection_id; public static String ProductInfoSection_product; @@ -2569,6 +2575,8 @@ public class PDEUIMessages extends NLS { public static String PluginGeneralInfoSection_singleton; + public static String PluginGeneralInfoSection_bundleshape; + public static String FragmentGeneralInfoSection_singleton; public static String ClassSearchParticipant_taskMessage; diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/GeneralInfoSection.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/GeneralInfoSection.java index 8f232502ef..c9cccda05d 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/GeneralInfoSection.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/GeneralInfoSection.java @@ -16,14 +16,18 @@ import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter; +import java.util.stream.Stream; + import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.layout.RowLayoutFactory; import org.eclipse.pde.core.IBaseModel; import org.eclipse.pde.core.IModelChangeProvider; import org.eclipse.pde.core.IModelChangedEvent; import org.eclipse.pde.core.plugin.IPluginBase; import org.eclipse.pde.core.plugin.IPluginModelBase; import org.eclipse.pde.core.plugin.PluginRegistry; +import org.eclipse.pde.internal.core.ICoreConstants; import org.eclipse.pde.internal.core.ibundle.IBundle; import org.eclipse.pde.internal.core.ibundle.IBundleModel; import org.eclipse.pde.internal.core.ibundle.IManifestHeader; @@ -41,6 +45,8 @@ import org.eclipse.pde.internal.ui.parts.FormEntry; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; @@ -55,7 +61,7 @@ * Provides the first section of the manifest editor describing the bundle id/name/version/etc. */ public abstract class GeneralInfoSection extends PDESection { - private static String PLATFORM_FILTER = "Eclipse-PlatformFilter"; //$NON-NLS-1$ + private static final String PLATFORM_FILTER = "Eclipse-PlatformFilter"; //$NON-NLS-1$ private FormEntry fIdEntry; private FormEntry fVersionEntry; @@ -77,6 +83,10 @@ public abstract class GeneralInfoSection extends PDESection { protected Button fSingleton; + private Button fBundleShapeDefault; + private Button fBundleShapeJar; + private Button fBundleShapeDir; + public GeneralInfoSection(PDEFormPage page, Composite parent) { super(page, parent, Section.DESCRIPTION); createClient(getSection(), page.getEditor().getToolkit()); @@ -102,6 +112,7 @@ protected void createClient(Section section, FormToolkit toolkit) { if (isBundle() && ((ManifestEditor) getPage().getEditor()).isEquinox()) createPlatformFilterEntry(client, toolkit, actionBars); createSpecificControls(client, toolkit, actionBars); + createBundleShape(client, toolkit, PDEUIMessages.PluginGeneralInfoSection_bundleshape); toolkit.paintBordersFor(client); addListeners(); @@ -340,6 +351,23 @@ public void refresh() { IManifestHeader header = getSingletonHeader(); fSingleton.setSelection(header instanceof BundleSymbolicNameHeader && ((BundleSymbolicNameHeader) header).isSingleton()); } + // Select the corresponding 'Bundle-Shape' radio button (eventually) + Stream.of(fBundleShapeDefault, fBundleShapeJar, fBundleShapeDir).forEach(b -> b.setSelection(false)); + Button selectedBundleShape = fBundleShapeDefault; + IManifestHeader header = getBundle().getManifestHeader(ICoreConstants.ECLIPSE_BUNDLE_SHAPE); + if (header != null) { + String value = header.getValue(); + if (value != null) { + selectedBundleShape = switch (value) { + case ICoreConstants.SHAPE_JAR -> fBundleShapeJar; + case ICoreConstants.SHAPE_DIR -> fBundleShapeDir; + default -> null; // unsupported value + }; + } + } + if (selectedBundleShape != null) { + selectedBundleShape.setSelection(true); + } super.refresh(); } @@ -400,4 +428,38 @@ protected void createSingleton(Composite parent, FormToolkit toolkit, IActionBar })); } + protected void createBundleShape(Composite parent, FormToolkit toolkit, String label) { + Composite c = new Composite(parent, SWT.NONE); + TableWrapData td = new TableWrapData(); + td.colspan = 3; + c.setLayoutData(td); + RowLayoutFactory.fillDefaults().spacing(5).applyTo(c); + toolkit.createLabel(c, label, SWT.NONE); + fBundleShapeDefault = toolkit.createButton(c, PDEUIMessages.GeneralInfoSection_BundleShape_default, SWT.RADIO); + fBundleShapeJar = toolkit.createButton(c, PDEUIMessages.GeneralInfoSection_BundleShape_jar, SWT.RADIO); + fBundleShapeDir = toolkit.createButton(c, PDEUIMessages.GeneralInfoSection_BundleShape_dir, SWT.RADIO); + fBundleShapeDir.setToolTipText(PDEUIMessages.GeneralInfoSection_BundleShape_dir_tooltip); + fBundleShapeJar.setToolTipText(PDEUIMessages.GeneralInfoSection_BundleShape_jar_tooltip); + fBundleShapeDefault.setToolTipText(PDEUIMessages.GeneralInfoSection_BundleShape_default_tooltip); + fBundleShapeDefault.setSelection(true); + fBundleShapeJar.addSelectionListener(SelectionListener + .widgetSelectedAdapter(event -> setBundleShapeHeader(event, ICoreConstants.SHAPE_JAR))); + fBundleShapeDir.addSelectionListener(SelectionListener + .widgetSelectedAdapter(event -> setBundleShapeHeader(event, ICoreConstants.SHAPE_DIR))); + fBundleShapeDefault.addSelectionListener( + SelectionListener.widgetSelectedAdapter(event -> setBundleShapeHeader(event, null))); + } + + private void setBundleShapeHeader(SelectionEvent event, String shape) { + if (((Button) event.widget).getSelection()) { + IBundle bundle = getBundle(); + if (shape != null) { + bundle.setHeader(ICoreConstants.ECLIPSE_BUNDLE_SHAPE, shape); + } else { + // Setting the header's value to null removes it (setting the + // header to null is not sufficient) + bundle.getManifestHeader(ICoreConstants.ECLIPSE_BUNDLE_SHAPE).setValue(null); + } + } + } } diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties index 19dedd80c8..95dd927b00 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties @@ -1510,6 +1510,7 @@ PluginWorkingSet_deselectAll_label=Dese&lect All PluginDevelopmentPage_presentation=Plug-in Manifest Editor Presentation PluginGeneralInfoSection_lazyStart=Activate this plug-in when one of its classes is loaded PluginGeneralInfoSection_singleton=This plug-in is a singleton +PluginGeneralInfoSection_bundleshape=Shape after P2 installation: FragmentGeneralInfoSection_singleton=This fragment is a singleton PluginWorkingSet_deselectAll_toolTip=Unselect all of these plug-ins for this working set. PluginListPage_initializeFromPlugins=&Initialize from the plug-ins list: @@ -2113,6 +2114,12 @@ Product_overview_exporting =
\

Use the Eclipse Product export wizard to package and export the product defined in this configuration.

\
GeneralInfoSection_desc=This section describes general information about the product. +GeneralInfoSection_BundleShape_default=default +GeneralInfoSection_BundleShape_dir=directory +GeneralInfoSection_BundleShape_jar=jar +GeneralInfoSection_BundleShape_default_tooltip=Install this bundle in the preferred shape, which is usually 'jar' but may vary depending on the content. +GeneralInfoSection_BundleShape_dir_tooltip=Enforce installing this bundle unpacked into a directory. +GeneralInfoSection_BundleShape_jar_tooltip=Enforce installing this bundle as jar. ProductInfoSection_desc=This section describes the launching product extension identifier and application. ProductInfoSection_id=ID: ProductInfoSection_product=Product: