diff options
author | Glenn Plouhinec | 2022-07-28 15:16:53 +0000 |
---|---|---|
committer | Jessy Mallet | 2023-03-08 10:27:42 +0000 |
commit | 309c09abfa30d0704b1d445d63fc51db95c22d25 (patch) | |
tree | d8c9d25cececcf9cfa1ecc09194109a4b944fa08 | |
parent | aeac8f788d64a92a5473751444e40a4428c1b759 (diff) | |
download | org.eclipse.papyrus-sirius-309c09abfa30d0704b1d445d63fc51db95c22d25.tar.gz org.eclipse.papyrus-sirius-309c09abfa30d0704b1d445d63fc51db95c22d25.tar.xz org.eclipse.papyrus-sirius-309c09abfa30d0704b1d445d63fc51db95c22d25.zip |
Bug 16: [Properties view] Create mono-valued reference Widget
The mono-valued reference widget is editable as the multi-valued
reference widget.
Ticket: https://github.com/PapyrusSirius/papyrus-desktop/issues/16
Change-Id: I45d737f5f56951957c86210d82d17698ae09e265
Signed-off-by: Glenn Plouhinec <glenn.plouhinec@obeo.fr>
2 files changed, 284 insertions, 3 deletions
diff --git a/plugins/uml/org.eclipse.papyrus.sirius.properties.eef.ide.ui.ext.widgets.editablereference/META-INF/MANIFEST.MF b/plugins/uml/org.eclipse.papyrus.sirius.properties.eef.ide.ui.ext.widgets.editablereference/META-INF/MANIFEST.MF index c698aa618..45006568d 100644 --- a/plugins/uml/org.eclipse.papyrus.sirius.properties.eef.ide.ui.ext.widgets.editablereference/META-INF/MANIFEST.MF +++ b/plugins/uml/org.eclipse.papyrus.sirius.properties.eef.ide.ui.ext.widgets.editablereference/META-INF/MANIFEST.MF @@ -14,7 +14,8 @@ Require-Bundle: org.eclipse.ui, org.eclipse.eef.common;bundle-version="[2.0.0,3.0.0)", org.eclipse.eef.common.ui;bundle-version="[2.0.0,3.0.0)", org.eclipse.eef.core.ext.widgets.reference;bundle-version="[2.0.0,3.0.0)", - org.eclipse.emf.edit.ui;bundle-version="2.20.0" + org.eclipse.emf.edit.ui;bundle-version="2.20.0", + org.eclipse.ui.forms Bundle-RequiredExecutionEnvironment: JavaSE-11 Automatic-Module-Name: org.eclipse.papyrus.sirius.properties.eef.ide.ui.ext.widgets.editablereference Bundle-ActivationPolicy: lazy diff --git a/plugins/uml/org.eclipse.papyrus.sirius.properties.eef.ide.ui.ext.widgets.editablereference/src/org/eclipse/papyrus/sirius/properties/eef/ide/ui/ext/widgets/editablereference/internal/SingleEditableReferenceLifecycleManager.java b/plugins/uml/org.eclipse.papyrus.sirius.properties.eef.ide.ui.ext.widgets.editablereference/src/org/eclipse/papyrus/sirius/properties/eef/ide/ui/ext/widgets/editablereference/internal/SingleEditableReferenceLifecycleManager.java index 2facacf31..bf189766e 100644 --- a/plugins/uml/org.eclipse.papyrus.sirius.properties.eef.ide.ui.ext.widgets.editablereference/src/org/eclipse/papyrus/sirius/properties/eef/ide/ui/ext/widgets/editablereference/internal/SingleEditableReferenceLifecycleManager.java +++ b/plugins/uml/org.eclipse.papyrus.sirius.properties.eef.ide.ui.ext.widgets.editablereference/src/org/eclipse/papyrus/sirius/properties/eef/ide/ui/ext/widgets/editablereference/internal/SingleEditableReferenceLifecycleManager.java @@ -13,29 +13,309 @@ *******************************************************************************/ package org.eclipse.papyrus.sirius.properties.eef.ide.ui.ext.widgets.editablereference.internal; +import java.util.List; + +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.eef.common.ui.api.IEEFFormContainer; import org.eclipse.eef.core.api.EditingContextAdapter; +import org.eclipse.eef.ide.ui.ext.widgets.reference.internal.EEFExtReferenceUIPlugin; import org.eclipse.eef.ide.ui.ext.widgets.reference.internal.EEFExtSingleReferenceLifecycleManager; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.papyrus.sirius.properties.eef.ext.widgets.editablereference.eefextwidgetseditablereference.EEFExtEditableReferenceDescription; +import org.eclipse.papyrus.sirius.properties.eef.ide.ui.ext.widgets.editablereference.Activator; import org.eclipse.sirius.common.interpreter.api.IInterpreter; import org.eclipse.sirius.common.interpreter.api.IVariableManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; /** * This lifecycle manager is used to handle the EEF Extension editable reference * widget for mono-valued EReferences. * - * @author gplouhinec + * @author <a href="mailto:glenn.plouhinec@obeo.fr">Glenn Plouhinec</a> * */ @SuppressWarnings("restriction") public class SingleEditableReferenceLifecycleManager extends EEFExtSingleReferenceLifecycleManager { + /** + * Tooltip of the "Edit" button. + */ + private static final String EDIT_BUTTON_TOOLTIP = "Edit the selected value"; //$NON-NLS-1$ + + /** + * The edit button used to edit the referenced element. + */ + protected Button editButton; + + /** + * The listener for the edit button. + */ + protected ButtonSelectionListener editButtonListener; + + /** + * Constructor. + * + * @param description the reference description to manage + * @param target the owner of the reference + * @param eReference the reference to display + * @param variableManager the variable manager which contain variables + * used by Interpreter to evaluate AQL expression + * @param interpreter the interpreter to evaluate AQL expressions + * @param editingContextAdapter the adapter used to modify model elements + */ public SingleEditableReferenceLifecycleManager(EEFExtEditableReferenceDescription description, EObject target, EReference eReference, IVariableManager variableManager, IInterpreter interpreter, EditingContextAdapter editingContextAdapter) { super(description, target, eReference, variableManager, interpreter, editingContextAdapter); - // TODO Auto-generated constructor stub } + @Override + protected void createMainControl(Composite parent, IEEFFormContainer formContainer) { + super.createMainControl(parent, formContainer); + this.controller = new EditableReferenceController(this, getWidgetDescription(), this.variableManager, + this.interpreter, this.editingContextAdapter, this.isEnabled()); + } + + @Override + protected EditableReferenceController getController() { + return (EditableReferenceController) this.controller; + } + + @Override + protected void setEnabled(boolean isEnabled) { + if (this.browseButton != null && !this.browseButton.isDisposed()) { + this.browseButton.setEnabled(isEnabled); + } + if (this.addButton != null && !this.addButton.isDisposed()) { + this.addButton.setEnabled(isEnabled); + } + boolean referenceExists = target.eGet(eReference) != null; + if (this.removeButton != null && !this.removeButton.isDisposed()) { + if (referenceExists) { + removeButton.setEnabled(isEnabled); + } else { + removeButton.setEnabled(false); + } + } + if (this.editButton != null && !this.editButton.isDisposed()) { + if (referenceExists) { + editButton.setEnabled(isEnabled); + } else { + editButton.setEnabled(false); + } + } + } + + @Override + protected EEFExtEditableReferenceDescription getWidgetDescription() { + return (EEFExtEditableReferenceDescription) this.description; + } + + @Override + public void aboutToBeShown() { + super.aboutToBeShown(); + this.initializeEditButton(); + } + + @Override + public void aboutToBeHidden() { + super.aboutToBeHidden(); + this.removeListener(this.editButton, this.editButtonListener); + } + + @Override + protected void createButtons(Composite parent) { + int enabledButtons = getButtonsNumber(); + parent.setLayout(new GridLayout(enabledButtons, true)); + if (!this.eReference.isContainment()) { + Image browseImage = ExtendedImageRegistry.INSTANCE.getImage(EEFExtReferenceUIPlugin.getPlugin() + .getImage(EEFExtReferenceUIPlugin.Implementation.BROWSE_ICON_PATH)); + this.browseButton = this.createButton(parent, browseImage); + } + Image addImage = ExtendedImageRegistry.INSTANCE.getImage( + EEFExtReferenceUIPlugin.getPlugin().getImage(EEFExtReferenceUIPlugin.Implementation.ADD_ICON_PATH)); + this.addButton = this.createButton(parent, addImage); + Image editImage = ExtendedImageRegistry.INSTANCE.getImage(Activator.getDefault().getImage(Activator.EDIT_ICON)); // $NON-NLS-1$ + this.editButton = this.createButton(parent, editImage); + if (!this.eReference.isRequired() && !this.eReference.isContainer()) { + Image removeImage = ExtendedImageRegistry.INSTANCE.getImage(EEFExtReferenceUIPlugin.getPlugin() + .getImage(EEFExtReferenceUIPlugin.Implementation.REMOVE_ICON_PATH)); + this.removeButton = this.createButton(parent, removeImage); + } + } + + @Override + protected int getButtonsNumber() { + int enabledButtons = 0; + // Browse button displayed or not + enabledButtons = enabledButtons + (!this.eReference.isContainment() ? 1 : 0); + // Remove button displayed or not + enabledButtons = enabledButtons + (!this.eReference.isRequired() && !this.eReference.isContainer() ? 1 : 0); + enabledButtons = enabledButtons + 2; // Add and Edit buttons are always enabled. + return enabledButtons; + } + + /** + * Initializes the edit button. + */ + protected void initializeEditButton() { + this.editButtonListener = new ButtonSelectionListener(this.editingContextAdapter, + () -> this.editButtonCallback()); + this.editButton.addSelectionListener(editButtonListener); + this.editButton.setToolTipText(EDIT_BUTTON_TOOLTIP); + } + + /** + * This method is called once the edit button is clicked in order to open the + * "edit dialog". + */ + protected void editButtonCallback() { + if (target != null) { + Object value = target.eGet(eReference); + if (value instanceof EObject) { + EObject eObject = (EObject) value; + int returnCode = getController().getPropertiesUtils().displayEditionProperties( + this.editingContextAdapter, eObject, this.variableManager, this.interpreter); + if (returnCode == Window.OK) { + this.refreshWithResize(); + } + } + } + return; + } + + /** + * + * {@inheritDoc} Overridden to wrap the Image and Label in a "clickable" + * Composite, in order to allow double clicking on the element. + * + * @see org.eclipse.eef.ide.ui.ext.widgets.reference.internal.EEFExtSingleReferenceLifecycleManager#createLabel(Composite)(org.eclipse.swt.widgets.Composite) + */ + @Override + protected void createLabel(Composite parent) { + // The parent's GridLayout was 3: one column for the image, one for the label + // and one for the buttonsComposite. The image and label will be wrapped here in + // a "clickable" Composite, so the parent's layout must be set to 2 columns. + GridLayout parentLayout = (GridLayout) parent.getLayout(); + parentLayout.numColumns = parentLayout.numColumns - 1; + + GridData gridData = new GridData(); + gridData.grabExcessHorizontalSpace = true; + gridData.horizontalAlignment = SWT.FILL; + + // This composite is used to fill the horizontal space without having the BORDER + // style for the whole widget. + Composite horizontalIntermediateComposite = new Composite(parent, SWT.NONE); + GridLayout gridLayout = new GridLayout(); + gridLayout.verticalSpacing = 0; + gridLayout.marginHeight = 0; + horizontalIntermediateComposite.setLayout(gridLayout); + horizontalIntermediateComposite.setLayoutData(gridData); + + GridData gd = new GridData(); + gd.grabExcessHorizontalSpace = false; + gd.horizontalAlignment = SWT.FILL; + + // Create the "clickable" area. + Composite clickableComposite = new Composite(horizontalIntermediateComposite, SWT.NONE); + GridLayout clickableGridLayout = new GridLayout(2, false); + clickableGridLayout.verticalSpacing = 0; + clickableGridLayout.marginHeight = 0; + clickableComposite.setLayout(clickableGridLayout); + clickableComposite.setLayoutData(gd); + + super.createLabel(clickableComposite); + + MouseListener listener = new MouseAdapter() { + @Override + public void mouseDoubleClick(MouseEvent e) { + if (isEnabled()) { + editingContextAdapter.performModelChange(() -> { + editButtonCallback(); + }); + } + } + }; + clickableComposite.addMouseListener(listener); + if (this.image != null) { + this.image.addMouseListener(listener); + } + if (this.text != null) { + this.text.addMouseListener(listener); + } + if (this.hyperlink != null) { + this.hyperlink.addMouseListener(listener); + } + } + + @Override + public void refresh() { + super.refresh(); + this.setEnabled(this.isEnabled()); + } + + /** + * Refresh the widget, buttons and size of the clickable composite which + * contains the label. + */ + private void refreshWithResize() { + this.refresh(); + text.requestLayout(); + } + + @Override + protected void addButtonCallback() { + List<Object> types = this.getController().getPropertiesUtils().getAllPossibleTypes(this.composedAdapterFactory, + this.editingContextAdapter, this.target, this.eReference); + int returnCode = Window.CANCEL; + if (types.size() == 1) { + EObject objectToCreate = (EObject) types.get(0); + ContainerUtil.addToContainer(this.target, this.eReference, objectToCreate); + returnCode = this.getController().getPropertiesUtils().displayCreationProperties(editingContextAdapter, + objectToCreate, variableManager, interpreter); + } else { + PapyrusEEFExtEObjectCreationWizard wizard = new PapyrusEEFExtEObjectCreationWizard(this.target, + this.eReference, this.editingContextAdapter, this.getController().getPropertiesUtils(), + this.variableManager, this.interpreter); + WizardDialog wizardDialog = new WizardDialog(this.image.getShell(), wizard); + wizardDialog.open(); + returnCode = wizard.getReturnCode(); + } + if (returnCode == Window.OK) { + this.refreshWithResize(); + } else { + throw new OperationCanceledException(); + } + } + + @Override + protected void browseButtonCallback() { + super.browseButtonCallback(); + this.refreshWithResize(); + } + + @Override + protected void removeButtonCallback() { + super.removeButtonCallback(); + this.refreshWithResize(); + } + + @Override + protected void initializeRemoveButton() { + if (!this.eReference.isRequired() && !this.eReference.isContainer()) { + super.initializeRemoveButton(); + } + } } |