diff options
| author | Alexander Fedorov | 2019-05-13 15:57:58 +0000 |
|---|---|---|
| committer | Julian Honnen | 2019-05-15 10:34:18 +0000 |
| commit | d78de91bf5e6a376f1077823af759faa356161f5 (patch) | |
| tree | 955671a121acd2a42110291d066321baa5d41f2c | |
| parent | f78e921f52642545aaea9251961eed2dde5bc99b (diff) | |
| download | eclipse.pde.ui-d78de91bf5e6a376f1077823af759faa356161f5.tar.gz eclipse.pde.ui-d78de91bf5e6a376f1077823af759faa356161f5.tar.xz eclipse.pde.ui-d78de91bf5e6a376f1077823af759faa356161f5.zip | |
Bug 547222 - [category] Allow to edit feature properties
Change-Id: I61b07dc91ee8f3c42f4148474cf070744a390084
Signed-off-by: Alexander Fedorov <alexander.fedorov@arsysop.ru>
Signed-off-by: Julian Honnen <julian.honnen@vector.com>
6 files changed, 381 insertions, 51 deletions
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 d2d800e2c5..9b4e3011b1 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014, 2018 IBM Corporation and others. + * Copyright (c) 2014, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -16,6 +16,7 @@ * Martin Karpisek <martin.karpisek@gmail.com> - Bug 438509 * Axel Richard (Obeo) - Bug 41353 - Launch configurations prototypes * Kit Lo (IBM) - Bug 244461 - Duplicating colon in error message + * Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 547222 *******************************************************************************/ package org.eclipse.pde.internal.ui; @@ -1924,6 +1925,13 @@ public class PDEUIMessages extends NLS { public static String CategoryDetails_alreadyExists; public static String CategoryDetails_alreadyExists_title; + public static String FeatureDetails_title; + public static String FeatureDetails_sectionDescription; + public static String FeatureDetails_id; + public static String FeatureDetails_version; + public static String FeatureDetails_url; + public static String FeatureDetails_include_url; + public static String FeaturesPage_title; public static String FeaturesPage_header; diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/category/CategorySection.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/category/CategorySection.java index a7d369ca56..796c8612b6 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/category/CategorySection.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/category/CategorySection.java @@ -685,7 +685,8 @@ public class CategorySection extends TreeSection implements IFeatureModelListene ISiteFeature featureCopy = adapter.feature; ISiteFeature[] features = fModel.getSite().getFeatures(); for (ISiteFeature feature : features) { - if (feature.getId().equals(featureCopy.getId()) && feature.getVersion().equals(featureCopy.getVersion())) { + if (Objects.equals(feature.getId(), featureCopy.getId()) + && Objects.equals(feature.getVersion(), featureCopy.getVersion())) { return feature; } } diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/category/FeatureDetailsSection.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/category/FeatureDetailsSection.java new file mode 100644 index 0000000000..e72b3fe384 --- /dev/null +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/category/FeatureDetailsSection.java @@ -0,0 +1,308 @@ +/******************************************************************************* + * Copyright (c) 2019 ArSysOp and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Alexander Fedorov <alexander.fedorov@arsysop.ru> - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.internal.ui.editor.category; + +import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.pde.core.IModelChangedEvent; +import org.eclipse.pde.internal.core.isite.ISiteFeature; +import org.eclipse.pde.internal.core.isite.ISiteModel; +import org.eclipse.pde.internal.ui.PDEPlugin; +import org.eclipse.pde.internal.ui.PDEUIMessages; +import org.eclipse.pde.internal.ui.editor.*; +import org.eclipse.pde.internal.ui.parts.FormEntry; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.*; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.forms.IFormPart; +import org.eclipse.ui.forms.IPartSelectionListener; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.Section; +import org.osgi.framework.Version; + +public class FeatureDetailsSection extends PDESection implements IPartSelectionListener { + + private static final String PROPERTY_ID = "id"; //$NON-NLS-1$ + private static final String PROPERTY_VERSION = "version"; //$NON-NLS-1$ + private static final String PROPERTY_URL = "url"; //$NON-NLS-1$ + + private ISiteFeature fCurrentSiteFeature; + private FormEntry fIdText; + private FormEntry fVersionText; + private FormEntry fUrlText; + private Button fIncludeUrlCheckbox; + private SelectionListener fRecomputeAdapter; + + public FeatureDetailsSection(PDEFormPage page, Composite parent) { + this(page, parent, PDEUIMessages.FeatureDetails_title, PDEUIMessages.FeatureDetails_sectionDescription, + SWT.NULL); + + } + + public FeatureDetailsSection(PDEFormPage page, Composite parent, String title, String desc, int toggleStyle) { + super(page, parent, Section.DESCRIPTION | toggleStyle); + getSection().setText(title); + getSection().setDescription(desc); + createClient(getSection(), page.getManagedForm().getToolkit()); + } + + private void applyValue(String property, String value) throws CoreException { + if (fCurrentSiteFeature == null) { + return; + } + if (property.equals(PROPERTY_ID)) { + fCurrentSiteFeature.setId(value); + } else if (property.equals(PROPERTY_VERSION)) { + fCurrentSiteFeature.setVersion(value); + } else if (property.equals(PROPERTY_URL)) { + fCurrentSiteFeature.setURL(value); + } + } + + @Override + public void cancelEdit() { + fIdText.cancelEdit(); + fVersionText.cancelEdit(); + super.cancelEdit(); + } + + @Override + public boolean canPaste(Clipboard clipboard) { + TransferData[] types = clipboard.getAvailableTypes(); + Transfer[] transfers = new Transfer[] {TextTransfer.getInstance(), RTFTransfer.getInstance()}; + for (TransferData type : types) { + for (Transfer transfer : transfers) { + if (transfer.isSupportedType(type)) { + return true; + } + } + } + return false; + } + + private void clearField(String property) { + if (property.equals(PROPERTY_ID)) { + fIdText.setValue(null, true); + } else if (property.equals(PROPERTY_VERSION)) { + fVersionText.setValue(null, true); + } else if (property.equals(PROPERTY_URL)) { + fUrlText.setValue(null, true); + fIncludeUrlCheckbox.setSelection(false); + } + } + + private void clearFields() { + fIdText.setValue(null, true); + fVersionText.setValue(null, true); + fUrlText.setValue(null, true); + fIncludeUrlCheckbox.setSelection(false); + } + + @Override + public void commit(boolean onSave) { + fIdText.commit(); + fVersionText.commit(); + super.commit(onSave); + } + + @Override + public void createClient(Section section, FormToolkit toolkit) { + section.setLayout(FormLayoutFactory.createClearGridLayout(false, 1)); + Composite container = toolkit.createComposite(section); + container.setLayout(FormLayoutFactory.createSectionClientGridLayout(false, 2)); + container.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + GridData data = new GridData(GridData.FILL_BOTH); + section.setLayoutData(data); + + fIdText = new FormEntry(container, toolkit, PDEUIMessages.FeatureDetails_id, null, false); + fIdText.setFormEntryListener(new FormEntryAdapter(this) { + @Override + public void textValueChanged(FormEntry text) { + try { + applyValue(PROPERTY_ID, text.getValue()); + if (fIncludeUrlCheckbox.getSelection()) { + applyUrl(true); + } + } catch (CoreException e) { + PDEPlugin.logException(e); + } + } + }); + limitTextWidth(fIdText); + fIdText.setEditable(isEditable()); + + fVersionText = new FormEntry(container, toolkit, PDEUIMessages.FeatureDetails_version, null, false); + fVersionText.setFormEntryListener(new FormEntryAdapter(this) { + + @Override + public void textValueChanged(FormEntry text) { + applyVersion(text.getValue()); + if (fIncludeUrlCheckbox.getSelection()) { + applyUrl(true); + } + } + + }); + limitTextWidth(fVersionText); + fVersionText.setEditable(isEditable()); + + fUrlText = new FormEntry(container, toolkit, PDEUIMessages.FeatureDetails_url, null, false); + limitTextWidth(fUrlText); + fUrlText.setEditable(false); + + toolkit.createLabel(container, ""); //$NON-NLS-1$ + fIncludeUrlCheckbox = toolkit.createButton(container, PDEUIMessages.FeatureDetails_include_url, SWT.CHECK); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalIndent = FormLayoutFactory.CONTROL_HORIZONTAL_INDENT; + fIncludeUrlCheckbox.setLayoutData(gd); + fRecomputeAdapter = widgetSelectedAdapter(e -> applyUrl(fIncludeUrlCheckbox.getSelection())); + fIncludeUrlCheckbox.addSelectionListener(fRecomputeAdapter); + fIncludeUrlCheckbox.setEnabled(isEditable()); + + toolkit.paintBordersFor(container); + section.setClient(container); + + ISiteModel model = (ISiteModel) getPage().getModel(); + if (model != null) { + model.addModelChangedListener(this); + } + } + + private void applyVersion(String version) { + String value = version; + if (value != null && value.isEmpty()) { + // do not store empty version + value = null; + } + if (value == null) { + applyUrl(false); + } + try { + applyValue(PROPERTY_VERSION, value); + } catch (CoreException e) { + PDEPlugin.logException(e); + } + + updateUrlEnablement(); + } + + private void applyUrl(boolean include) { + String value = include ? recomputeUrl() : null; + try { + applyValue(PROPERTY_URL, value); + } catch (CoreException e) { + PDEPlugin.logException(e); + } + } + + private String recomputeUrl() { + if (fCurrentSiteFeature == null) { + return null; + } + StringBuilder sb = new StringBuilder(); + sb.append("features/").append(fCurrentSiteFeature.getId()).append("_"); //$NON-NLS-1$ //$NON-NLS-2$ + try { + sb.append(new Version(fCurrentSiteFeature.getVersion())); + } catch (Exception e) { + sb.append("0.0.0"); //$NON-NLS-1$ + } + sb.append(".jar"); //$NON-NLS-1$ + return sb.toString(); + } + + private void updateUrlEnablement() { + fIncludeUrlCheckbox.setEnabled(isEditable() && !fVersionText.getValue().isEmpty()); + } + + @Override + public void dispose() { + ISiteModel model = (ISiteModel) getPage().getModel(); + if (model != null) { + model.removeModelChangedListener(this); + } + super.dispose(); + } + + private void limitTextWidth(FormEntry entry) { + GridData gd = (GridData) entry.getText().getLayoutData(); + gd.widthHint = 30; + } + + @Override + public void modelChanged(IModelChangedEvent e) { + markStale(); + } + + @Override + public void refresh() { + if (fCurrentSiteFeature == null) { + clearFields(); + super.refresh(); + return; + } + setValue(PROPERTY_ID); + setValue(PROPERTY_VERSION); + setValue(PROPERTY_URL); + updateUrlEnablement(); + super.refresh(); + } + + @Override + public void selectionChanged(IFormPart part, ISelection selection) { + ISiteFeature siteFeature = null; + if (selection instanceof IStructuredSelection) { + IStructuredSelection structured = (IStructuredSelection) selection; + Object o = structured.getFirstElement(); + if (o instanceof ISiteFeature) { + siteFeature = (ISiteFeature) o; + } else if (o instanceof SiteFeatureAdapter) { + siteFeature = ((SiteFeatureAdapter) o).feature; + } + } + fCurrentSiteFeature = siteFeature; + refresh(); + } + + @Override + public void setFocus() { + if (fIdText != null) { + fIdText.getText().setFocus(); + } + } + + private void setValue(String property) { + if (fCurrentSiteFeature == null) { + clearField(property); + } else { + if (property.equals(PROPERTY_ID)) { + fIdText.setValue(fCurrentSiteFeature.getId(), true); + } else if (property.equals(PROPERTY_VERSION)) { + fVersionText.setValue(fCurrentSiteFeature.getVersion(), true); + } else if (property.equals(PROPERTY_URL)) { + fIncludeUrlCheckbox.removeSelectionListener(fRecomputeAdapter); + String url = fCurrentSiteFeature.getURL(); + fIncludeUrlCheckbox.setSelection(url != null); + fUrlText.setValue(url, true); + fIncludeUrlCheckbox.addSelectionListener(fRecomputeAdapter); + } + } + } +} diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/category/IUsPage.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/category/IUsPage.java index 5c0773c004..3ff21fc4d4 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/category/IUsPage.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/category/IUsPage.java @@ -1,21 +1,24 @@ /******************************************************************************* -. -. This -* program and the accompanying materials are made available under the terms of -* the Eclipse Public License 2.0 which accompanies this distribution, and is -t https://www.eclipse.org/legal/epl-2.0/ -t -t SPDX-License-Identifier: EPL-2.0 -* -* Contributors: -* EclipseSource - initial API and implementation -* IBM Corporation - Renamed from FeaturesPage -* Red Hat Inc. - Support for nested categories -* Martin Karpisek <martin.karpisek@gmail.com> - Bug 296392 -******************************************************************************/ + * Copyright (c) 2009, 2019 EclipseSource and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * EclipseSource - initial API and implementation + * IBM Corporation - Renamed from FeaturesPage + * Red Hat Inc. - Support for nested categories + * Martin Karpisek <martin.karpisek@gmail.com> - Bug 296392 + * Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 547222 + ******************************************************************************/ package org.eclipse.pde.internal.ui.editor.category; import org.eclipse.pde.internal.core.isite.ISiteCategoryDefinition; +import org.eclipse.pde.internal.core.isite.ISiteFeature; import org.eclipse.pde.internal.ui.*; import org.eclipse.pde.internal.ui.editor.*; import org.eclipse.swt.widgets.Composite; @@ -60,8 +63,11 @@ public class IUsPage extends PDEFormPage { @Override public IDetailsPage getPage(Object key) { - if (key.equals(ISiteCategoryDefinition.class) || key.equals(SiteCategoryDefinitionAdapter.class)) + if (key.equals(ISiteCategoryDefinition.class) || key.equals(SiteCategoryDefinitionAdapter.class)) { return createCategoryDetails(); + } else if (key.equals(ISiteFeature.class) || key.equals(SiteFeatureAdapter.class)) { + return createFeatureDetails(); + } return null; } }); @@ -98,6 +104,20 @@ public class IUsPage extends PDEFormPage { }; } + private IDetailsPage createFeatureDetails() { + return new PDEDetailsSections() { + @Override + protected PDESection[] createSections(PDEFormPage page, Composite parent) { + return new PDESection[] { new FeatureDetailsSection(getPage(), parent) }; + } + + @Override + public String getContextId() { + return CategoryInputContext.CONTEXT_ID; + } + }; + } + @Override protected String getHelpResource() { return IHelpContextIds.CATEGORY_EDITOR; diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/category/SiteFeatureAdapter.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/category/SiteFeatureAdapter.java index c3c8070a1a..788a154cc8 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/category/SiteFeatureAdapter.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/category/SiteFeatureAdapter.java @@ -1,19 +1,22 @@ /******************************************************************************* -. -. This -* program and the accompanying materials are made available under the terms of -* the Eclipse Public License 2.0 which accompanies this distribution, and is -t https://www.eclipse.org/legal/epl-2.0/ -t -t SPDX-License-Identifier: EPL-2.0 -* -* Contributors: -* EclipseSource - initial API and implementation -******************************************************************************/ + * Copyright (c) 2009, 2019 EclipseSource and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * EclipseSource - initial API and implementation + * Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 547222 + ******************************************************************************/ package org.eclipse.pde.internal.ui.editor.category; import java.io.PrintWriter; import java.io.Serializable; +import java.util.Objects; import org.eclipse.pde.core.IWritable; import org.eclipse.pde.internal.core.isite.ISiteFeature; @@ -35,8 +38,8 @@ public class SiteFeatureAdapter implements Serializable, IWritable { } /* - * For retaining selectiong in the tree, when modyfing or moving features, - * SiteFeatureAdapter are equal if features are equal (same ID and version) + * For retaining selection in the tree, when modyfing or moving features, + * SiteFeatureAdapter are equal if features are equal * * @see java.lang.Object#equals(java.lang.Object) */ @@ -44,32 +47,13 @@ public class SiteFeatureAdapter implements Serializable, IWritable { public boolean equals(Object obj) { if (obj instanceof SiteFeatureAdapter) { SiteFeatureAdapter adapter = (SiteFeatureAdapter) obj; - String id = feature.getId(); - String id2 = adapter.feature.getId(); - boolean sameFeature = id != null && id2 != null && id.equals(id2); - if (sameFeature) { - String version = feature.getVersion(); - String version2 = adapter.feature.getVersion(); - sameFeature = version != null && version2 != null && version.equals(version2); - } - boolean sameCategory = adapter.category != null && category != null ? adapter.category.equals(category) : true; - return sameFeature && sameCategory; + return Objects.equals(feature, adapter.feature); } return super.equals(obj); } @Override public int hashCode() { - if (feature.getId() == null) { - return super.hashCode(); - } - int code = feature.getId().hashCode(); - if (feature.getVersion() != null) { - code += feature.getVersion().hashCode(); - } - if (category != null) { - code += category.hashCode(); - } - return code; + return feature.hashCode(); } } 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 e8a8131af1..93dd22d2fd 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 @@ -18,6 +18,7 @@ # Martin Karpisek <martin.karpisek@gmail.com> - Bug 438509 # Axel Richard (Obeo) - Bug 41353 - Launch configurations prototypes # Kit Lo (IBM) - Bug 244461 - Duplicating colon in error message +# Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 547222 ############################################################################### ##################################### # PDE resource strings @@ -1742,6 +1743,14 @@ CategoryDetails_desc = De&scription: CategoryDetails_alreadyExists=The category must have a unique id. CategoryDetails_alreadyExists_title = Invalid category id +FeatureDetails_title = Feature Properties +FeatureDetails_sectionDescription = Provide an identifier and a version for each feature.\n\ +"*" denotes a required field. +FeatureDetails_id = &ID*: +FeatureDetails_version = &Version: +FeatureDetails_url = URL +FeatureDetails_include_url=Include URL + FeaturesPage_title = Site Map FeaturesPage_header = Update Site Map |
