diff options
author | Johannes Faltermeier | 2018-05-02 09:42:52 +0000 |
---|---|---|
committer | Johannes Faltermeier | 2018-05-02 15:29:29 +0000 |
commit | 4fa398a9a8edf3502a6bf88dfe11b9f22ac0470d (patch) | |
tree | 9a0fb45a850307f44451f6e7167457470e3525a4 | |
parent | 09801e0b052b1db62f9a7782a8b9b28e2d9e41bf (diff) | |
download | org.eclipse.emf.ecp.core-4fa398a9a8edf3502a6bf88dfe11b9f22ac0470d.tar.gz org.eclipse.emf.ecp.core-4fa398a9a8edf3502a6bf88dfe11b9f22ac0470d.tar.xz org.eclipse.emf.ecp.core-4fa398a9a8edf3502a6bf88dfe11b9f22ac0470d.zip |
Bug 534267 - CompoundControlSWTRenderer should work similar to
SimpleControlSWTRenderer
* Create CompoundControl without DMR because this produces nasty log
messages because the DMR is invalid
* Show readonly and labelALignment in tooling when creating a compound
control
* Introduce SimpleControlSWTRendererUtil which allows to reuse functions
related to grid cell creation
* Introduce AbstractControlSWTRendererUtil which allows to reuse
functions related to reading values from the template
* CompoundControlSWTRenderer will try to reuse the validation cell from
the first child in order to nicely integrate with existing control
renderers
* Render label as one label which respects alignment/style bits
* Adjust test cases accordingly
Change-Id: I75985397373d59fbe804c32d94b34df78d5a8966
Signed-off-by: Johannes Faltermeier <jfaltermeier@eclipsesource.com>
11 files changed, 1094 insertions, 262 deletions
diff --git a/bundles/org.eclipse.emf.ecp.view.compoundcontrol.model.edit/src/org/eclipse/emf/ecp/view/spi/compoundcontrol/model/provider/CompoundcontrolItemProviderAdapterFactory.java b/bundles/org.eclipse.emf.ecp.view.compoundcontrol.model.edit/src/org/eclipse/emf/ecp/view/spi/compoundcontrol/model/provider/CompoundcontrolItemProviderAdapterFactory.java index 458cfe2df8..0969277460 100644 --- a/bundles/org.eclipse.emf.ecp.view.compoundcontrol.model.edit/src/org/eclipse/emf/ecp/view/spi/compoundcontrol/model/provider/CompoundcontrolItemProviderAdapterFactory.java +++ b/bundles/org.eclipse.emf.ecp.view.compoundcontrol.model.edit/src/org/eclipse/emf/ecp/view/spi/compoundcontrol/model/provider/CompoundcontrolItemProviderAdapterFactory.java @@ -20,13 +20,11 @@ import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.common.util.ResourceLocator; import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecp.view.spi.compoundcontrol.model.VCompoundControl; import org.eclipse.emf.ecp.view.spi.compoundcontrol.model.VCompoundcontrolFactory; import org.eclipse.emf.ecp.view.spi.compoundcontrol.model.VCompoundcontrolPackage; import org.eclipse.emf.ecp.view.spi.compoundcontrol.model.util.CompoundcontrolAdapterFactory; import org.eclipse.emf.ecp.view.spi.model.VContainer; import org.eclipse.emf.ecp.view.spi.model.VView; -import org.eclipse.emf.ecp.view.spi.model.VViewFactory; import org.eclipse.emf.ecp.view.spi.model.VViewPackage; import org.eclipse.emf.ecp.view.spi.model.util.ViewSwitch; import org.eclipse.emf.edit.command.CommandParameter; @@ -320,47 +318,31 @@ public class CompoundcontrolItemProviderAdapterFactory extends } /** - * <!-- begin-user-doc --> - * View case. - * - * @param object object - * @return object - * <!-- end-user-doc --> + * <!-- begin-user-doc --> <!-- end-user-doc --> * - * @generated NOT + * @generated */ @Override public Object caseView(VView object) { newChildDescriptors.add(createChildParameter(VViewPackage.Literals.VIEW__CHILDREN, - createCompoundControlWithDummyDMR())); + VCompoundcontrolFactory.eINSTANCE.createCompoundControl())); return null; } /** - * <!-- begin-user-doc --> - * Container case. - * - * @param object object - * @return object - * <!-- end-user-doc --> + * <!-- begin-user-doc --> <!-- end-user-doc --> * - * @generated NOT + * @generated */ @Override public Object caseContainer(VContainer object) { newChildDescriptors.add(createChildParameter(VViewPackage.Literals.CONTAINER__CHILDREN, - createCompoundControlWithDummyDMR())); + VCompoundcontrolFactory.eINSTANCE.createCompoundControl())); return null; } - private VCompoundControl createCompoundControlWithDummyDMR() { - final VCompoundControl compoundControl = VCompoundcontrolFactory.eINSTANCE.createCompoundControl(); - compoundControl.setDomainModelReference(VViewFactory.eINSTANCE.createFeaturePathDomainModelReference()); - return compoundControl; - } - /** * <!-- begin-user-doc -->. <!-- end-user-doc --> * diff --git a/bundles/org.eclipse.emf.ecp.view.compoundcontrol.swt/.settings/.api_filters b/bundles/org.eclipse.emf.ecp.view.compoundcontrol.swt/.settings/.api_filters index c69ac15f9d..070a15553b 100644 --- a/bundles/org.eclipse.emf.ecp.view.compoundcontrol.swt/.settings/.api_filters +++ b/bundles/org.eclipse.emf.ecp.view.compoundcontrol.swt/.settings/.api_filters @@ -21,12 +21,24 @@ <message_argument value="CompoundControlSWTRenderer(VCompoundControl, ViewModelContext, ReportService)"/> </message_arguments> </filter> + <filter comment="SPI Change 1.17.0" id="338722907"> + <message_arguments> + <message_argument value="org.eclipse.emf.ecp.view.spi.compoundcontrol.swt.CompoundControlSWTRenderer"/> + <message_argument value="CompoundControlSWTRenderer(VCompoundControl, ViewModelContext, ReportService, EMFFormsLabelProvider, EMFFormsRendererFactory, VTViewTemplateProvider)"/> + </message_arguments> + </filter> <filter comment="EMFForms 1.6 SPI Change" id="338792546"> <message_arguments> <message_argument value="org.eclipse.emf.ecp.view.spi.compoundcontrol.swt.CompoundControlSWTRenderer"/> <message_argument value="getGridDescription(SWTGridDescription)"/> </message_arguments> </filter> + <filter comment="SPI Change 1.17.0" id="338792546"> + <message_arguments> + <message_argument value="org.eclipse.emf.ecp.view.spi.compoundcontrol.swt.CompoundControlSWTRenderer"/> + <message_argument value="getLabelAlignment()"/> + </message_arguments> + </filter> <filter comment="EMFForms 1.6 SPI Change" id="338792546"> <message_arguments> <message_argument value="org.eclipse.emf.ecp.view.spi.compoundcontrol.swt.CompoundControlSWTRenderer"/> diff --git a/bundles/org.eclipse.emf.ecp.view.compoundcontrol.swt/META-INF/MANIFEST.MF b/bundles/org.eclipse.emf.ecp.view.compoundcontrol.swt/META-INF/MANIFEST.MF index 1103e27b92..4db592ba2e 100644 --- a/bundles/org.eclipse.emf.ecp.view.compoundcontrol.swt/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.emf.ecp.view.compoundcontrol.swt/META-INF/MANIFEST.MF @@ -14,7 +14,8 @@ Require-Bundle: org.eclipse.emf.ecp.view.core.swt;bundle-version="[1.17.0,1.18.0 org.eclipse.emfforms.core.services;bundle-version="[1.17.0,1.18.0]", org.eclipse.emf.databinding;bundle-version="[1.3.0,2.0.0)", org.eclipse.emfforms.swt.core.di;bundle-version="[1.17.0,1.18.0]", - org.eclipse.emf.ecp.view.template.model;bundle-version="[1.17.0,1.18.0]" + org.eclipse.emf.ecp.view.template.model;bundle-version="[1.17.0,1.18.0]", + org.eclipse.emfforms.core.services.emf;bundle-version="[1.17.0,1.18.0)" Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Import-Package: javax.inject;version="1.0.0", org.eclipse.emfforms.spi.common.report;version="[1.17.0,1.18.0]", diff --git a/bundles/org.eclipse.emf.ecp.view.compoundcontrol.swt/src/org/eclipse/emf/ecp/view/spi/compoundcontrol/swt/CompoundControlSWTRenderer.java b/bundles/org.eclipse.emf.ecp.view.compoundcontrol.swt/src/org/eclipse/emf/ecp/view/spi/compoundcontrol/swt/CompoundControlSWTRenderer.java index e6a41ea279..47665e0439 100644 --- a/bundles/org.eclipse.emf.ecp.view.compoundcontrol.swt/src/org/eclipse/emf/ecp/view/spi/compoundcontrol/swt/CompoundControlSWTRenderer.java +++ b/bundles/org.eclipse.emf.ecp.view.compoundcontrol.swt/src/org/eclipse/emf/ecp/view/spi/compoundcontrol/swt/CompoundControlSWTRenderer.java @@ -11,19 +11,28 @@ */ package org.eclipse.emf.ecp.view.spi.compoundcontrol.swt; +import java.util.AbstractMap; +import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import javax.inject.Inject; -import org.eclipse.core.databinding.Binding; import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.UpdateValueStrategy; import org.eclipse.core.databinding.observable.value.IObservableValue; -import org.eclipse.emf.common.util.EList; +import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.databinding.EMFDataBindingContext; +import org.eclipse.emf.databinding.EMFUpdateValueStrategy; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecp.view.model.common.util.RendererUtil; import org.eclipse.emf.ecp.view.spi.compoundcontrol.model.VCompoundControl; import org.eclipse.emf.ecp.view.spi.context.ViewModelContext; +import org.eclipse.emf.ecp.view.spi.core.swt.AbstractControlSWTRendererUtil; +import org.eclipse.emf.ecp.view.spi.core.swt.SimpleControlSWTRendererUtil; import org.eclipse.emf.ecp.view.spi.model.LabelAlignment; import org.eclipse.emf.ecp.view.spi.model.VContainedElement; import org.eclipse.emf.ecp.view.spi.model.VControl; @@ -33,22 +42,23 @@ import org.eclipse.emf.ecp.view.spi.renderer.NoRendererFoundException; import org.eclipse.emf.ecp.view.spi.swt.layout.LayoutProviderHelper; import org.eclipse.emf.ecp.view.spi.swt.reporting.RenderingFailedReport; import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider; -import org.eclipse.emf.ecp.view.template.style.alignment.model.AlignmentType; -import org.eclipse.emf.ecp.view.template.style.alignment.model.VTControlLabelAlignmentStyleProperty; import org.eclipse.emf.ecp.view.template.style.labelwidth.model.VTLabelWidthStyleProperty; +import org.eclipse.emf.ecp.view.template.style.mandatory.model.VTMandatoryStyleProperty; import org.eclipse.emfforms.common.Optional; import org.eclipse.emfforms.spi.common.report.AbstractReport; import org.eclipse.emfforms.spi.common.report.ReportService; +import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException; +import org.eclipse.emfforms.spi.core.services.databinding.emf.EMFFormsDatabindingEMF; import org.eclipse.emfforms.spi.core.services.label.EMFFormsLabelProvider; import org.eclipse.emfforms.spi.core.services.label.NoLabelFoundException; import org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer; import org.eclipse.emfforms.spi.swt.core.EMFFormsNoRendererException; import org.eclipse.emfforms.spi.swt.core.EMFFormsRendererFactory; +import org.eclipse.emfforms.spi.swt.core.SWTDataElementIdHelper; import org.eclipse.emfforms.spi.swt.core.layout.GridDescriptionFactory; import org.eclipse.emfforms.spi.swt.core.layout.SWTGridCell; import org.eclipse.emfforms.spi.swt.core.layout.SWTGridDescription; -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.databinding.swt.WidgetProperties; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; @@ -63,7 +73,7 @@ import org.eclipse.swt.widgets.Layout; */ public class CompoundControlSWTRenderer extends AbstractSWTRenderer<VCompoundControl> { - private static final String SEPARATOR = "/"; //$NON-NLS-1$ + private static final String SEPARATOR = " / "; //$NON-NLS-1$ private SWTGridDescription rendererGridDescription; @@ -75,6 +85,10 @@ public class CompoundControlSWTRenderer extends AbstractSWTRenderer<VCompoundCon private final VTViewTemplateProvider viewTemplateProvider; + private boolean firstControlValidationIconUsed; + + private final EMFFormsDatabindingEMF databindingService; + /** * Default constructor. * @@ -84,7 +98,8 @@ public class CompoundControlSWTRenderer extends AbstractSWTRenderer<VCompoundCon * @param labelProvider the {@link EMFFormsLabelProvider label provider} * @param rendererFactory the {@link EMFFormsRendererFactory renderer factory} * @param viewTemplateProvider {@link VTViewTemplateProvider} - * @since 1.16 + * @param databindingService {@link EMFFormsDatabindingEMF} + * @since 1.17 */ @Inject public CompoundControlSWTRenderer( @@ -93,11 +108,13 @@ public class CompoundControlSWTRenderer extends AbstractSWTRenderer<VCompoundCon ReportService reportService, EMFFormsLabelProvider labelProvider, EMFFormsRendererFactory rendererFactory, - VTViewTemplateProvider viewTemplateProvider) { + VTViewTemplateProvider viewTemplateProvider, + EMFFormsDatabindingEMF databindingService) { super(vElement, viewContext, reportService); this.labelProvider = labelProvider; this.rendererFactory = rendererFactory; this.viewTemplateProvider = viewTemplateProvider; + this.databindingService = databindingService; } /** @@ -121,6 +138,14 @@ public class CompoundControlSWTRenderer extends AbstractSWTRenderer<VCompoundCon } /** + * @return the {@link EMFFormsDatabindingEMF}. + * @since 1.17 + */ + protected EMFFormsDatabindingEMF getDatabindingService() { + return databindingService; + } + + /** * Returns the {@link DataBindingContext}. * * @return the databining context @@ -138,6 +163,7 @@ public class CompoundControlSWTRenderer extends AbstractSWTRenderer<VCompoundCon * @since 1.16 */ protected LinkedHashMap<VContainedElement, AbstractSWTRenderer<VElement>> getElementRendererMap() { + initChildRendererMap(); return elementRendererMap; } @@ -157,22 +183,28 @@ public class CompoundControlSWTRenderer extends AbstractSWTRenderer<VCompoundCon @Override public SWTGridDescription getGridDescription(SWTGridDescription gridDescription) { if (rendererGridDescription == null) { - rendererGridDescription = GridDescriptionFactory.INSTANCE.createSimpleGrid(1, 2, this); - - final SWTGridCell label = rendererGridDescription.getGrid().get(0); - label.setHorizontalGrab(false); - label.setVerticalGrab(false); - label.setVerticalFill(false); - final Optional<Integer> labelWidth = getLabelWidth(); - if (labelWidth.isPresent()) { - label.setPreferredSize( - labelWidth.get(), - label.getPreferredSize() == null ? SWT.DEFAULT : label.getPreferredSize().y); + final int columns = SimpleControlSWTRendererUtil + .showLabel(getVElement(), getReportService(), getClass().getName()) ? 3 : 2; + + rendererGridDescription = GridDescriptionFactory.INSTANCE.createEmptyGridDescription(); + rendererGridDescription.setRows(1); + rendererGridDescription.setColumns(columns); + + final List<SWTGridCell> grid = new ArrayList<SWTGridCell>(); + + if (columns == 3) { + final SWTGridCell labelCell = SimpleControlSWTRendererUtil + .createLabelCell(grid.size(), this, getLabelWidth()); + grid.add(labelCell); } - final SWTGridCell controls = rendererGridDescription.getGrid().get(1); - controls.setVerticalGrab(false); - controls.setVerticalFill(false); + final SWTGridCell validationCell = SimpleControlSWTRendererUtil.createValidationCell(grid.size(), this); + grid.add(validationCell); + + final SWTGridCell controlCel = SimpleControlSWTRendererUtil.createControlCell(grid.size(), this); + grid.add(controlCel); + + rendererGridDescription.setGrid(grid); } return rendererGridDescription; } @@ -180,10 +212,16 @@ public class CompoundControlSWTRenderer extends AbstractSWTRenderer<VCompoundCon @Override protected Control renderControl(SWTGridCell cell, Composite parent) throws NoRendererFoundException, NoPropertyDescriptorFoundExeption { - switch (cell.getColumn()) { + int controlIndex = cell.getColumn(); + if (getVElement().getLabelAlignment() == LabelAlignment.NONE) { + controlIndex++; + } + switch (controlIndex) { case 0: return createLabel(parent); case 1: + return createValidationIcon(parent); + case 2: return createControls(parent); default: throw new IllegalArgumentException( @@ -200,51 +238,93 @@ public class CompoundControlSWTRenderer extends AbstractSWTRenderer<VCompoundCon * @since 1.8 */ protected Control createLabel(Composite parent) { - final EList<VControl> controls = getVElement().getControls(); + final Label label = new Label(parent, getLabelStyleBits()); + label.setData(CUSTOM_VARIANT, "org_eclipse_emf_ecp_control_label"); //$NON-NLS-1$ + SWTDataElementIdHelper + .setElementIdDataWithSubId(label, getVElement(), "control_label", getViewModelContext()); //$NON-NLS-1$ + label.setBackground(parent.getBackground()); + + final IObservableValue textObservable = WidgetProperties.text().observe(label); + final Map<IObservableValue, Map.Entry<VControl, EStructuralFeature>> displayNameObservables = getLabelDisplayNameObservables(); + + for (final IObservableValue displayNameObservable : displayNameObservables.keySet()) { + getDataBindingContext().bindValue( + textObservable, + displayNameObservable, + new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER), + new CompoundControlDisplayNameUpdateValueStrategy(displayNameObservables)); + } - final Composite labelComposite = new Composite(parent, SWT.NONE); - GridLayoutFactory.fillDefaults().numColumns(2 * controls.size() - - 1).equalWidth(false).applyTo(labelComposite); + final IObservableValue tooltipObservable = WidgetProperties.tooltipText().observe(label); + final List<IObservableValue> labelDescriptionObservables = getLabelDescriptionObservables(); + for (final IObservableValue descriptionObservable : labelDescriptionObservables) { + getDataBindingContext().bindValue( + tooltipObservable, + descriptionObservable, + new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER), + new EMFUpdateValueStrategy() { + @Override + public Object convert(Object value) { + final StringBuilder stringBuilder = new StringBuilder(); + for (final IObservableValue obs : labelDescriptionObservables) { + if (stringBuilder.length() > 0) { + stringBuilder.append("\n"); //$NON-NLS-1$ + } + stringBuilder.append(obs.getValue()); + } + return stringBuilder.toString(); + } + }); - final AlignmentType labelAlignment = getLabelAlignment(); + } - for (int i = 0; i < controls.size(); i++) { - if (i != 0) { - final Label separatorLabel = new Label(labelComposite, SWT.NONE); - GridDataFactory.fillDefaults().grab(false, false).align(SWT.FILL, SWT.CENTER).applyTo(separatorLabel); - separatorLabel.setText(SEPARATOR); - } + return label; + } - boolean grab = false; - int stylebits = SWT.NONE; - if (labelAlignment == AlignmentType.LEFT && i == controls.size() - 1) { - /* if left, the last label should grow */ - grab = true; - } else if (labelAlignment == AlignmentType.RIGHT && i == 0) { - /* if right, first column should grow and right alignment */ - grab = true; - stylebits = SWT.RIGHT; - } + private Map<IObservableValue, Map.Entry<VControl, EStructuralFeature>> getLabelDisplayNameObservables() { + final LinkedHashMap<IObservableValue, Entry<VControl, EStructuralFeature>> displayNames = new LinkedHashMap<IObservableValue, Map.Entry<VControl, EStructuralFeature>>(); - final Label label = new Label(labelComposite, stylebits); - GridDataFactory.fillDefaults().grab(grab, false).align(SWT.FILL, SWT.CENTER).applyTo(label); - final VControl control = controls.get(i); + for (final VControl control : getVElement().getControls()) { try { - @SuppressWarnings("deprecation") - final IObservableValue targetValue = org.eclipse.jface.databinding.swt.SWTObservables - .observeText(label); - final IObservableValue modelValue = getLabelProvider().getDisplayName(control.getDomainModelReference(), - getViewModelContext().getDomainModel()); - final Binding bindValue = getDataBindingContext().bindValue(targetValue, modelValue); - bindValue.updateModelToTarget(); + final IObservableValue displayName = labelProvider + .getDisplayName(control.getDomainModelReference(), getViewModelContext().getDomainModel()); + + final EStructuralFeature feature = getDatabindingService() + .getValueProperty(control.getDomainModelReference(), getViewModelContext().getDomainModel()) + .getStructuralFeature(); + + displayNames.put(displayName, + new AbstractMap.SimpleEntry<VControl, EStructuralFeature>(control, feature)); } catch (final NoLabelFoundException ex) { - getReportService().report(new AbstractReport(ex)); + getReportService().report(new AbstractReport(ex, IStatus.WARNING)); + } catch (final DatabindingFailedException ex) { + getReportService().report(new AbstractReport(ex, IStatus.WARNING)); } + } + return displayNames; + } + + private List<IObservableValue> getLabelDescriptionObservables() { + final List<IObservableValue> labelDescriptionObservables = new ArrayList<IObservableValue>(); + for (final VControl control : getVElement().getControls()) { + try { + labelDescriptionObservables.add(labelProvider.getDescription(control.getDomainModelReference(), + getViewModelContext().getDomainModel())); + } catch (final NoLabelFoundException ex) { + getReportService().report(new AbstractReport(ex, IStatus.WARNING)); + } } + return labelDescriptionObservables; + } - labelComposite.setData(CUSTOM_VARIANT, "org_eclipse_emf_ecp_control_label"); //$NON-NLS-1$ - return labelComposite; + /** + * @return the style bits for the control's label + * @since 1.17 + */ + protected int getLabelStyleBits() { + return AbstractControlSWTRendererUtil + .getLabelStyleBits(getViewTemplateProvider(), getVElement(), getViewModelContext()); } /** @@ -264,19 +344,60 @@ public class CompoundControlSWTRenderer extends AbstractSWTRenderer<VCompoundCon } /** - * @return the style bits for the control's label - * @since 1.16 + * Return the validation cell of the fist child. If no children or strange first cell, return a dummy validation + * icon. + * + * @param parent the parent to render on + * @return the validation control + * + * @throws NoRendererFoundException this is thrown when a renderer cannot be found + * @throws NoPropertyDescriptorFoundExeption this is thrown when no property descriptor can be found + * @since 1.17 */ - protected AlignmentType getLabelAlignment() { - final VTControlLabelAlignmentStyleProperty styleProperty = RendererUtil.getStyleProperty( - getViewTemplateProvider(), - getVElement(), - getViewModelContext(), - VTControlLabelAlignmentStyleProperty.class); - if (styleProperty == null) { - return AlignmentType.LEFT; + protected Control createValidationIcon(Composite parent) + throws NoRendererFoundException, NoPropertyDescriptorFoundExeption { + if (getVElement().getControls().isEmpty()) { + return createDummyValidationIcon(parent); } - return styleProperty.getType(); + final AbstractSWTRenderer<VElement> renderer = getElementRendererMap() + .get(getVElement().getControls().get(0)); + if (renderer == null) { + return createDummyValidationIcon(parent); + } + final SWTGridDescription gridDescription = renderer + .getGridDescription(GridDescriptionFactory.INSTANCE.createEmptyGridDescription()); + if (gridDescription.getColumns() < 2) { + return createDummyValidationIcon(parent); + } + /* use child renderer cell */ + setFirstControlValidationIconUsed(true); + final SWTGridCell validationCell = gridDescription.getGrid().get(0); + return validationCell.getRenderer().render(validationCell, parent); + } + + /** + * Whether the first cell of the first child control was used to renderer our validation icon. + * + * @param used <code>true</code> if used, <code>false</code> otherwise + * @since 1.17 + */ + protected void setFirstControlValidationIconUsed(boolean used) { + firstControlValidationIconUsed = used; + } + + /** + * Creates the validation icon of the first cell of the first child may not be used as the validation icon. + * + * @param parent the parent + * @return the validation icon + * @since 1.17 + */ + protected Control createDummyValidationIcon(Composite parent) { + final Label validationLabel = new Label(parent, SWT.NONE); + SWTDataElementIdHelper + .setElementIdDataWithSubId(validationLabel, getVElement(), "control_validation", getViewModelContext()); //$NON-NLS-1$ + validationLabel.setBackground(parent.getBackground()); + return validationLabel; } /** @@ -287,11 +408,11 @@ public class CompoundControlSWTRenderer extends AbstractSWTRenderer<VCompoundCon * @since 1.8 */ protected Control createControls(Composite parent) { - return createControls(parent, 0); + return createControls(parent, firstControlValidationIconUsed ? 1 : 0); } /** - * Creates the controls composite. May skip the first cells of the child renderers. + * Creates the controls composite. May skip the first cell(s). * * @param parent the parent composite * @param cellsToSkip number of cells to skip @@ -299,8 +420,6 @@ public class CompoundControlSWTRenderer extends AbstractSWTRenderer<VCompoundCon * @since 1.16 */ protected Control createControls(Composite parent, int cellsToSkip) { - initChildRendererMap(); - final Composite columnComposite = new Composite(parent, SWT.NONE); columnComposite.setBackground(parent.getBackground()); @@ -352,7 +471,7 @@ public class CompoundControlSWTRenderer extends AbstractSWTRenderer<VCompoundCon * @since 1.16 */ protected void initChildRendererMap() { - if (getElementRendererMap() != null) { + if (elementRendererMap != null) { return; } setElementRendererMap(new LinkedHashMap<VContainedElement, AbstractSWTRenderer<VElement>>()); @@ -422,4 +541,53 @@ public class CompoundControlSWTRenderer extends AbstractSWTRenderer<VCompoundCon } super.dispose(); } + + /** + * Model to target for display names which concats all display names. + * + * @author Johannes Faltermeier + * + */ + private final class CompoundControlDisplayNameUpdateValueStrategy extends EMFUpdateValueStrategy { + private final Map<IObservableValue, Entry<VControl, EStructuralFeature>> displayNameObservables; + + /** + * @param displayNameObservables + */ + private CompoundControlDisplayNameUpdateValueStrategy( + Map<IObservableValue, Entry<VControl, EStructuralFeature>> displayNameObservables) { + this.displayNameObservables = displayNameObservables; + } + + @Override + public Object convert(Object value) { + final StringBuilder stringBuilder = new StringBuilder(); + + for (final Entry<IObservableValue, Map.Entry<VControl, EStructuralFeature>> obs : displayNameObservables + .entrySet()) { + if (stringBuilder.length() > 0) { + stringBuilder.append(SEPARATOR); + } + stringBuilder.append( + getDisplayName(obs.getKey(), obs.getValue().getKey(), obs.getValue().getValue())); + + } + return stringBuilder.toString(); + } + + private Object getDisplayName( + final IObservableValue obs, + VControl control, + EStructuralFeature structuralFeature) { + + final Object value = obs.getValue(); + String extra = ""; //$NON-NLS-1$ + final VTMandatoryStyleProperty mandatoryStyle = AbstractControlSWTRendererUtil + .getMandatoryStyle(getViewTemplateProvider(), control, getViewModelContext()); + if (mandatoryStyle.isHighliteMandatoryFields() && structuralFeature.getLowerBound() > 0) { + extra = mandatoryStyle.getMandatoryMarker(); + } + return value + extra; + } + } } diff --git a/bundles/org.eclipse.emf.ecp.view.compoundcontrol.tooling/viewmodel/CompoundControl.view b/bundles/org.eclipse.emf.ecp.view.compoundcontrol.tooling/viewmodel/CompoundControl.view index b2b4df0e45..18c38d24a9 100644 --- a/bundles/org.eclipse.emf.ecp.view.compoundcontrol.tooling/viewmodel/CompoundControl.view +++ b/bundles/org.eclipse.emf.ecp.view.compoundcontrol.tooling/viewmodel/CompoundControl.view @@ -1,10 +1,20 @@ <?xml version="1.0" encoding="ASCII"?> <org.eclipse.emf.ecp.view.model:View xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:org.eclipse.emf.ecp.view.model="http://org/eclipse/emf/ecp/view/model/1170" xmi:id="_qh0foGaPEeWid_wgrZaAaw" name="CompoundControl"> - <ecorePaths>/org.eclipse.emf.ecp.view.compoundcontrol.model/model/compoundcontrol.ecore</ecorePaths> <rootEClass href="http://org/eclipse/emf/ecp/view/compoundcontrol/model#//CompoundControl"/> <children xsi:type="org.eclipse.emf.ecp.view.model:Control" xmi:id="_qiHakGaPEeWid_wgrZaAaw" name="Control name"> <domainModelReference xsi:type="org.eclipse.emf.ecp.view.model:FeaturePathDomainModelReference" xmi:id="_qiHakWaPEeWid_wgrZaAaw"> <domainModelEFeature xsi:type="ecore:EAttribute" href="http://org/eclipse/emf/ecp/view/model/1170#//Element/name"/> </domainModelReference> </children> + <children xsi:type="org.eclipse.emf.ecp.view.model:Control" xmi:id="_pOkQ4E3kEeiiiv2tJoAZjg" name="Control readonly"> + <domainModelReference xsi:type="org.eclipse.emf.ecp.view.model:FeaturePathDomainModelReference" xmi:id="_pOk38E3kEeiiiv2tJoAZjg"> + <domainModelEFeature xsi:type="ecore:EAttribute" href="http://org/eclipse/emf/ecp/view/model/1170#//Element/readonly"/> + </domainModelReference> + </children> + <children xsi:type="org.eclipse.emf.ecp.view.model:Control" xmi:id="_pOn7QE3kEeiiiv2tJoAZjg" name="Control labelAlignment"> + <domainModelReference xsi:type="org.eclipse.emf.ecp.view.model:FeaturePathDomainModelReference" xmi:id="_pOn7QU3kEeiiiv2tJoAZjg"> + <domainModelEFeature xsi:type="ecore:EAttribute" href="http://org/eclipse/emf/ecp/view/model/1170#//Control/labelAlignment"/> + </domainModelReference> + </children> + <ecorePaths>/org.eclipse.emf.ecp.view.compoundcontrol.model/model/compoundcontrol.ecore</ecorePaths> </org.eclipse.emf.ecp.view.model:View> diff --git a/bundles/org.eclipse.emf.ecp.view.core.swt/src/org/eclipse/emf/ecp/view/spi/core/swt/AbstractControlSWTRenderer.java b/bundles/org.eclipse.emf.ecp.view.core.swt/src/org/eclipse/emf/ecp/view/spi/core/swt/AbstractControlSWTRenderer.java index 12830ceecd..108ac33e52 100644 --- a/bundles/org.eclipse.emf.ecp.view.core.swt/src/org/eclipse/emf/ecp/view/spi/core/swt/AbstractControlSWTRenderer.java +++ b/bundles/org.eclipse.emf.ecp.view.core.swt/src/org/eclipse/emf/ecp/view/spi/core/swt/AbstractControlSWTRenderer.java @@ -13,7 +13,6 @@ package org.eclipse.emf.ecp.view.spi.core.swt; import java.util.LinkedHashMap; import java.util.Map; -import java.util.Set; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.UpdateValueStrategy; @@ -24,7 +23,6 @@ import org.eclipse.emf.databinding.EMFDataBindingContext; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecp.edit.spi.swt.util.SWTValidationHelper; -import org.eclipse.emf.ecp.view.model.common.util.RendererUtil; import org.eclipse.emf.ecp.view.spi.context.ViewModelContext; import org.eclipse.emf.ecp.view.spi.model.LabelAlignment; import org.eclipse.emf.ecp.view.spi.model.ModelChangeListener; @@ -34,12 +32,8 @@ import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference; import org.eclipse.emf.ecp.view.spi.renderer.NoPropertyDescriptorFoundExeption; import org.eclipse.emf.ecp.view.spi.renderer.NoRendererFoundException; import org.eclipse.emf.ecp.view.spi.swt.reporting.RenderingFailedReport; -import org.eclipse.emf.ecp.view.template.model.VTStyleProperty; import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider; -import org.eclipse.emf.ecp.view.template.style.alignment.model.VTControlLabelAlignmentStyleProperty; -import org.eclipse.emf.ecp.view.template.style.mandatory.model.VTMandatoryFactory; import org.eclipse.emf.ecp.view.template.style.mandatory.model.VTMandatoryStyleProperty; -import org.eclipse.emf.ecp.view.template.style.wrap.model.VTLabelWrapStyleProperty; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emfforms.spi.common.report.AbstractReport; @@ -462,37 +456,8 @@ public abstract class AbstractControlSWTRenderer<VCONTROL extends VControl> exte * @since 1.16 */ protected int getLabelStyleBits() { - final VTControlLabelAlignmentStyleProperty alignmentStyleProperty = RendererUtil.getStyleProperty( - getVTViewTemplateProvider(), - getVElement(), - getViewModelContext(), - VTControlLabelAlignmentStyleProperty.class); - - int bits = SWT.NONE; - - if (alignmentStyleProperty != null) { - switch (alignmentStyleProperty.getType()) { - case RIGHT: - bits |= SWT.RIGHT; - break; - default: - break; - } - } - - final VTLabelWrapStyleProperty wrapStyleProperty = RendererUtil.getStyleProperty( - getVTViewTemplateProvider(), - getVElement(), - getViewModelContext(), - VTLabelWrapStyleProperty.class); - - if (wrapStyleProperty != null) { - if (VTLabelWrapStyleProperty.class.cast(wrapStyleProperty).isWrapLabel()) { - bits |= SWT.WRAP; - } - } - - return bits; + return AbstractControlSWTRendererUtil + .getLabelStyleBits(getVTViewTemplateProvider(), getVElement(), getViewModelContext()); } /** @@ -508,21 +473,8 @@ public abstract class AbstractControlSWTRenderer<VCONTROL extends VControl> exte } private VTMandatoryStyleProperty getMandatoryStyle() { - if (vtViewTemplateProvider == null) { - return getDefaultStyle(); - } - final Set<VTStyleProperty> styleProperties = vtViewTemplateProvider - .getStyleProperties(getVElement(), getViewModelContext()); - for (final VTStyleProperty styleProperty : styleProperties) { - if (VTMandatoryStyleProperty.class.isInstance(styleProperty)) { - return (VTMandatoryStyleProperty) styleProperty; - } - } - return getDefaultStyle(); - } - - private VTMandatoryStyleProperty getDefaultStyle() { - return VTMandatoryFactory.eINSTANCE.createMandatoryStyleProperty(); + return AbstractControlSWTRendererUtil + .getMandatoryStyle(vtViewTemplateProvider, getVElement(), getViewModelContext()); } /** diff --git a/bundles/org.eclipse.emf.ecp.view.core.swt/src/org/eclipse/emf/ecp/view/spi/core/swt/AbstractControlSWTRendererUtil.java b/bundles/org.eclipse.emf.ecp.view.core.swt/src/org/eclipse/emf/ecp/view/spi/core/swt/AbstractControlSWTRendererUtil.java new file mode 100644 index 0000000000..eee2eba793 --- /dev/null +++ b/bundles/org.eclipse.emf.ecp.view.core.swt/src/org/eclipse/emf/ecp/view/spi/core/swt/AbstractControlSWTRendererUtil.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2011-2018 EclipseSource Muenchen GmbH 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: + * Johannes Faltermeier - initial API and implementation + ******************************************************************************/ +package org.eclipse.emf.ecp.view.spi.core.swt; + +import java.util.Set; + +import org.eclipse.emf.ecp.view.model.common.util.RendererUtil; +import org.eclipse.emf.ecp.view.spi.context.ViewModelContext; +import org.eclipse.emf.ecp.view.spi.model.VControl; +import org.eclipse.emf.ecp.view.template.model.VTStyleProperty; +import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider; +import org.eclipse.emf.ecp.view.template.style.alignment.model.VTControlLabelAlignmentStyleProperty; +import org.eclipse.emf.ecp.view.template.style.mandatory.model.VTMandatoryFactory; +import org.eclipse.emf.ecp.view.template.style.mandatory.model.VTMandatoryStyleProperty; +import org.eclipse.emf.ecp.view.template.style.wrap.model.VTLabelWrapStyleProperty; +import org.eclipse.swt.SWT; + +/** + * Holds some Util methods for the {@link AbstractControlSWTRendererUtil} which may be reused by renderers which cannot + * inherit from {@link AbstractControlSWTRendererUtil} but want to reuse functionality. + * + * @author Johannes Faltermeier + * @since 1.17 + * + */ +public final class AbstractControlSWTRendererUtil { + + private AbstractControlSWTRendererUtil() { + /* util */ + } + + /** + * The style bits for a control label. + * + * @param viewTemplateProvider the {@link VTViewTemplateProvider} + * @param control the {@link VControl} + * @param viewModelContext the {@link ViewModelContext} + * @return the style bits + */ + public static int getLabelStyleBits(VTViewTemplateProvider viewTemplateProvider, VControl control, + ViewModelContext viewModelContext) { + final VTControlLabelAlignmentStyleProperty alignmentStyleProperty = RendererUtil.getStyleProperty( + viewTemplateProvider, + control, + viewModelContext, + VTControlLabelAlignmentStyleProperty.class); + + int bits = SWT.NONE; + + if (alignmentStyleProperty != null) { + switch (alignmentStyleProperty.getType()) { + case RIGHT: + bits |= SWT.RIGHT; + break; + default: + break; + } + } + + final VTLabelWrapStyleProperty wrapStyleProperty = RendererUtil.getStyleProperty( + viewTemplateProvider, + control, + viewModelContext, + VTLabelWrapStyleProperty.class); + + if (wrapStyleProperty != null) { + if (VTLabelWrapStyleProperty.class.cast(wrapStyleProperty).isWrapLabel()) { + bits |= SWT.WRAP; + } + } + + return bits; + } + + /** + * The {@link VTMandatoryStyleProperty} property. + * + * @param vtViewTemplateProvider the {@link VTViewTemplateProvider} + * @param control the {@link VControl} + * @param viewModelContext the {@link ViewModelContext} + * @return the property + */ + public static VTMandatoryStyleProperty getMandatoryStyle( + VTViewTemplateProvider vtViewTemplateProvider, + VControl control, + ViewModelContext viewModelContext) { + + if (vtViewTemplateProvider == null) { + return getDefaultMandatoryStyle(); + } + final Set<VTStyleProperty> styleProperties = vtViewTemplateProvider + .getStyleProperties(control, viewModelContext); + for (final VTStyleProperty styleProperty : styleProperties) { + if (VTMandatoryStyleProperty.class.isInstance(styleProperty)) { + return (VTMandatoryStyleProperty) styleProperty; + } + } + return getDefaultMandatoryStyle(); + } + + private static VTMandatoryStyleProperty getDefaultMandatoryStyle() { + return VTMandatoryFactory.eINSTANCE.createMandatoryStyleProperty(); + } + +} diff --git a/bundles/org.eclipse.emf.ecp.view.core.swt/src/org/eclipse/emf/ecp/view/spi/core/swt/SimpleControlSWTRenderer.java b/bundles/org.eclipse.emf.ecp.view.core.swt/src/org/eclipse/emf/ecp/view/spi/core/swt/SimpleControlSWTRenderer.java index d1e7055ebe..fa45c27015 100644 --- a/bundles/org.eclipse.emf.ecp.view.core.swt/src/org/eclipse/emf/ecp/view/spi/core/swt/SimpleControlSWTRenderer.java +++ b/bundles/org.eclipse.emf.ecp.view.core.swt/src/org/eclipse/emf/ecp/view/spi/core/swt/SimpleControlSWTRenderer.java @@ -11,14 +11,12 @@ ******************************************************************************/ package org.eclipse.emf.ecp.view.spi.core.swt; -import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import org.eclipse.core.databinding.observable.IObserving; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.core.databinding.property.value.IValueProperty; -import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; @@ -42,7 +40,6 @@ import org.eclipse.emf.ecp.view.template.style.unsettable.model.VTUnsettableStyl import org.eclipse.emf.edit.command.SetCommand; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emfforms.common.Optional; -import org.eclipse.emfforms.spi.common.report.AbstractReport; import org.eclipse.emfforms.spi.common.report.ReportService; import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException; import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedReport; @@ -59,7 +56,6 @@ import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; @@ -228,8 +224,6 @@ public abstract class SimpleControlSWTRenderer extends AbstractControlSWTRendere private static final String ICONS_UNSET_FEATURE = "icons/unset_feature.png"; //$NON-NLS-1$ private static final String ICONS_SET_FEATURE = "icons/set_feature.png"; //$NON-NLS-1$ - private static final Point VALIDATION_PREFERRED_SIZE = new Point(16, 17); - /** * Default constructor. * @@ -261,7 +255,8 @@ public abstract class SimpleControlSWTRenderer extends AbstractControlSWTRendere @Override public SWTGridDescription getGridDescription(SWTGridDescription gridDescription) { if (rendererGridDescription == null) { - final int columns = showLabel() ? 3 : 2; + final int columns = SimpleControlSWTRendererUtil + .showLabel(getVElement(), getReportService(), getClass().getName()) ? 3 : 2; rendererGridDescription = GridDescriptionFactory.INSTANCE.createEmptyGridDescription(); rendererGridDescription.setRows(1); @@ -285,22 +280,6 @@ public abstract class SimpleControlSWTRenderer extends AbstractControlSWTRendere return rendererGridDescription; } - private boolean showLabel() { - switch (getVElement().getLabelAlignment()) { - case DEFAULT: - case LEFT: - return true; - case NONE: - return false; - default: - getReportService().report(new AbstractReport(MessageFormat.format( - "Label alignment {0} is not supported by renderer {1}. Label alignment set to default.", //$NON-NLS-1$ - getVElement().getLabelAlignment().getLiteral(), getClass().getName()), IStatus.INFO)); - getVElement().setLabelAlignment(LabelAlignment.DEFAULT); - return true; - } - } - /** * Creates the label cell if necessary. * @@ -309,19 +288,7 @@ public abstract class SimpleControlSWTRenderer extends AbstractControlSWTRendere * @since 1.9 */ protected SWTGridCell createLabelCell(int column) { - final SWTGridCell labelCell = new SWTGridCell(0, column, this); - labelCell.setHorizontalGrab(false); - labelCell.setVerticalGrab(false); - labelCell.setHorizontalFill(false); - labelCell.setHorizontalAlignment(SWTGridCell.Alignment.BEGINNING); - labelCell.setVerticalFill(false); - labelCell.setVerticalAlignment(SWTGridCell.Alignment.CENTER); - labelCell.setRenderer(this); - final Optional<Integer> labelWidth = getLabelWidth(); - if (labelWidth.isPresent()) { - labelCell.setPreferredSize(labelWidth.get(), SWT.DEFAULT); - } - return labelCell; + return SimpleControlSWTRendererUtil.createLabelCell(column, this, getLabelWidth()); } /** @@ -348,16 +315,7 @@ public abstract class SimpleControlSWTRenderer extends AbstractControlSWTRendere * @since 1.9 */ protected SWTGridCell createValidationCell(int column) { - final SWTGridCell validationCell = new SWTGridCell(0, column, this); - validationCell.setHorizontalGrab(false); - validationCell.setVerticalGrab(false); - validationCell.setHorizontalFill(false); - validationCell.setHorizontalAlignment(SWTGridCell.Alignment.CENTER); - validationCell.setVerticalFill(false); - validationCell.setVerticalAlignment(SWTGridCell.Alignment.CENTER); - validationCell.setRenderer(this); - validationCell.setPreferredSize(VALIDATION_PREFERRED_SIZE); - return validationCell; + return SimpleControlSWTRendererUtil.createValidationCell(column, this); } /** @@ -368,14 +326,7 @@ public abstract class SimpleControlSWTRenderer extends AbstractControlSWTRendere * @since 1.9 */ protected SWTGridCell createControlCell(int column) { - final SWTGridCell controlCell = new SWTGridCell(0, column, this); - controlCell.setHorizontalGrab(true); - controlCell.setVerticalGrab(false); - controlCell.setHorizontalFill(true); - controlCell.setVerticalFill(true); - controlCell.setVerticalAlignment(SWTGridCell.Alignment.CENTER); - controlCell.setRenderer(this); - return controlCell; + return SimpleControlSWTRendererUtil.createControlCell(column, this); } /** diff --git a/bundles/org.eclipse.emf.ecp.view.core.swt/src/org/eclipse/emf/ecp/view/spi/core/swt/SimpleControlSWTRendererUtil.java b/bundles/org.eclipse.emf.ecp.view.core.swt/src/org/eclipse/emf/ecp/view/spi/core/swt/SimpleControlSWTRendererUtil.java new file mode 100644 index 0000000000..3baf036a82 --- /dev/null +++ b/bundles/org.eclipse.emf.ecp.view.core.swt/src/org/eclipse/emf/ecp/view/spi/core/swt/SimpleControlSWTRendererUtil.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2011-2018 EclipseSource Muenchen GmbH 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: + * Johannes Faltermeier - initial API and implementation + ******************************************************************************/ +package org.eclipse.emf.ecp.view.spi.core.swt; + +import java.text.MessageFormat; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.emf.ecp.view.spi.model.LabelAlignment; +import org.eclipse.emf.ecp.view.spi.model.VControl; +import org.eclipse.emf.ecp.view.spi.model.VElement; +import org.eclipse.emfforms.common.Optional; +import org.eclipse.emfforms.spi.common.report.AbstractReport; +import org.eclipse.emfforms.spi.common.report.ReportService; +import org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer; +import org.eclipse.emfforms.spi.swt.core.layout.SWTGridCell; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; + +/** + * Holds some Util methods for the {@link SimpleControlSWTRenderer} which may be reused by renderers which cannot + * inherit from {@link SimpleControlSWTRenderer} but want to reuse functionality. + * + * @author Johannes Faltermeier + * @since 1.17 + * + */ +public final class SimpleControlSWTRendererUtil { + + private static final Point VALIDATION_PREFERRED_SIZE = new Point(16, 17); + + private SimpleControlSWTRendererUtil() { + /* util */ + } + + /** + * Whether to create a label cell on the left in the same row. + * + * @param control the rendered {@link VControl} + * @param reportService the {@link ReportService} + * @param rendererName the name of the current renderer for logging + * @return <code>true</code> if label grid cell should be created, <code>false</code> otherwise + */ + public static boolean showLabel(VControl control, ReportService reportService, String rendererName) { + switch (control.getLabelAlignment()) { + case DEFAULT: + case LEFT: + return true; + case NONE: + return false; + default: + reportService.report(new AbstractReport(MessageFormat.format( + "Label alignment {0} is not supported by renderer {1}. Label alignment set to default.", //$NON-NLS-1$ + control.getLabelAlignment().getLiteral(), rendererName), IStatus.INFO)); + control.setLabelAlignment(LabelAlignment.DEFAULT); + return true; + } + } + + /** + * Creates the cell for the label. + * + * @param column the column index + * @param renderer the renderer + * @param labelWidth the width for the label + * @return the grid cell + */ + public static SWTGridCell createLabelCell( + int column, + AbstractSWTRenderer<? extends VElement> renderer, + Optional<Integer> labelWidth) { + + final SWTGridCell labelCell = new SWTGridCell(0, column, renderer); + labelCell.setHorizontalGrab(false); + labelCell.setVerticalGrab(false); + labelCell.setHorizontalFill(false); + labelCell.setHorizontalAlignment(SWTGridCell.Alignment.BEGINNING); + labelCell.setVerticalFill(false); + labelCell.setVerticalAlignment(SWTGridCell.Alignment.CENTER); + labelCell.setRenderer(renderer); + if (labelWidth.isPresent()) { + labelCell.setPreferredSize(labelWidth.get(), SWT.DEFAULT); + } + return labelCell; + } + + /** + * Creates the validation cell. + * + * @param column the column index. + * @param renderer the renderer + * @return the grid cell + */ + public static SWTGridCell createValidationCell(int column, AbstractSWTRenderer<? extends VElement> renderer) { + final SWTGridCell validationCell = new SWTGridCell(0, column, renderer); + validationCell.setHorizontalGrab(false); + validationCell.setVerticalGrab(false); + validationCell.setHorizontalFill(false); + validationCell.setHorizontalAlignment(SWTGridCell.Alignment.CENTER); + validationCell.setVerticalFill(false); + validationCell.setVerticalAlignment(SWTGridCell.Alignment.CENTER); + validationCell.setRenderer(renderer); + validationCell.setPreferredSize(VALIDATION_PREFERRED_SIZE); + return validationCell; + } + + /** + * Creates the control cell. + * + * @param column the column index + * @param renderer the renderer + * @return the grid cell + */ + public static SWTGridCell createControlCell(int column, AbstractSWTRenderer<? extends VElement> renderer) { + final SWTGridCell controlCell = new SWTGridCell(0, column, renderer); + controlCell.setHorizontalGrab(true); + controlCell.setVerticalGrab(false); + controlCell.setHorizontalFill(true); + controlCell.setVerticalFill(true); + controlCell.setVerticalAlignment(SWTGridCell.Alignment.CENTER); + controlCell.setRenderer(renderer); + return controlCell; + } +} diff --git a/tests/org.eclipse.emf.ecp.view.compoundcontrol.swt.test/CompoundControlSWTRenderer_ITest.launch b/tests/org.eclipse.emf.ecp.view.compoundcontrol.swt.test/CompoundControlSWTRenderer_ITest.launch index df39a83ce3..632da157c8 100644 --- a/tests/org.eclipse.emf.ecp.view.compoundcontrol.swt.test/CompoundControlSWTRenderer_ITest.launch +++ b/tests/org.eclipse.emf.ecp.view.compoundcontrol.swt.test/CompoundControlSWTRenderer_ITest.launch @@ -32,8 +32,8 @@ <stringAttribute key="pde.version" value="3.3"/> <stringAttribute key="product" value="org.eclipse.platform.ide"/> <booleanAttribute key="run_in_ui_thread" value="true"/> -<stringAttribute key="selected_target_plugins" value="com.ibm.icu@default:default,javax.annotation@default:default,javax.inject@default:default,javax.servlet@default:default,org.apache.ant@default:default,org.apache.batik.css*1.7.0.v201011041433@default:default,org.apache.batik.util*1.7.0.v201011041433@default:default,org.apache.batik.util.gui*1.7.0.v200903091627@default:default,org.apache.commons.codec@default:default,org.apache.commons.jxpath@default:default,org.apache.commons.logging@default:default,org.apache.felix.scr@default:default,org.eclipse.ant.core@default:default,org.eclipse.compare.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding*1.5.0.v20150422-0725@default:default,org.eclipse.core.databinding*1.6.100.v20170515-1119@default:default,org.eclipse.core.databinding.observable*1.5.0.v20150422-0725@default:default,org.eclipse.core.databinding.observable*1.6.100.v20170515-1119@default:default,org.eclipse.core.databinding.property*1.5.0.v20150422-0725@default:default,org.eclipse.core.databinding.property*1.6.100.v20170515-1119@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.resources@default:default,org.eclipse.core.runtime@default:true,org.eclipse.core.variables@default:default,org.eclipse.e4.core.commands@default:default,org.eclipse.e4.core.contexts@default:default,org.eclipse.e4.core.di.annotations@default:default,org.eclipse.e4.core.di.extensions.supplier@default:default,org.eclipse.e4.core.di.extensions@default:default,org.eclipse.e4.core.di@default:default,org.eclipse.e4.core.services@default:default,org.eclipse.e4.emf.xpath@default:default,org.eclipse.e4.ui.bindings@default:default,org.eclipse.e4.ui.css.core@default:default,org.eclipse.e4.ui.css.swt.theme@default:default,org.eclipse.e4.ui.css.swt@default:default,org.eclipse.e4.ui.di@default:default,org.eclipse.e4.ui.model.workbench@default:default,org.eclipse.e4.ui.services@default:default,org.eclipse.e4.ui.widgets@default:default,org.eclipse.e4.ui.workbench.addons.swt@default:default,org.eclipse.e4.ui.workbench.renderers.swt@default:default,org.eclipse.e4.ui.workbench.swt@default:default,org.eclipse.e4.ui.workbench3@default:default,org.eclipse.e4.ui.workbench@default:default,org.eclipse.emf.common.ui@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.databinding.edit@default:default,org.eclipse.emf.databinding@default:default,org.eclipse.emf.ecore.change@default:default,org.eclipse.emf.ecore.xmi@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.emf.edit.ui@default:default,org.eclipse.emf.edit@default:default,org.eclipse.emf.emfstore.client@default:default,org.eclipse.emf.emfstore.common.model@default:default,org.eclipse.emf.emfstore.common@default:default,org.eclipse.emf.emfstore.examplemodel.edit@default:default,org.eclipse.emf.emfstore.examplemodel@default:default,org.eclipse.emf.emfstore.migration@default:default,org.eclipse.emf.emfstore.server.model@default:default,org.eclipse.emf.emfstore.server@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.bidi@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.event@default:default,org.eclipse.equinox.p2.core@default:default,org.eclipse.equinox.p2.engine@default:default,org.eclipse.equinox.p2.metadata.repository@default:default,org.eclipse.equinox.p2.metadata@default:default,org.eclipse.equinox.p2.repository@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.region@default:false,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.security@default:default,org.eclipse.equinox.transforms.hook@default:false,org.eclipse.equinox.util@default:default,org.eclipse.equinox.weaving.hook@default:false,org.eclipse.help@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.jface.text@default:default,org.eclipse.jface@default:default,org.eclipse.net4j.util@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services@default:default,org.eclipse.osgi.util@default:default,org.eclipse.osgi@-1:true,org.eclipse.swt.gtk.linux.x86_64@default:default,org.eclipse.swt@default:default,org.eclipse.swtbot.ant.junit@default:false,org.eclipse.team.core@default:default,org.eclipse.text@default:default,org.eclipse.ui.forms@default:default,org.eclipse.ui.ide@default:default,org.eclipse.ui.trace@default:default,org.eclipse.ui.views@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.ui@default:default,org.eclipse.update.configurator@3:true,org.hamcrest.core@default:default,org.junit@default:default,org.mockito.mockito-core-hamcrest-modified@default:default,org.objenesis@default:default,org.tukaani.xz@default:default,org.w3c.css.sac@default:default,org.w3c.dom.events@default:default,org.w3c.dom.smil*1.0.1.v200903091627@default:default,org.w3c.dom.svg@default:default"/> -<stringAttribute key="selected_workspace_plugins" value="org.eclipse.emf.ecp.common.ui@default:default,org.eclipse.emf.ecp.common@default:default,org.eclipse.emf.ecp.core@default:default,org.eclipse.emf.ecp.edit.swt@default:default,org.eclipse.emf.ecp.edit@default:default,org.eclipse.emf.ecp.emfstore.core@default:default,org.eclipse.emf.ecp.makeithappen.model@default:default,org.eclipse.emf.ecp.test.common@default:default,org.eclipse.emf.ecp.ui.view.swt@default:default,org.eclipse.emf.ecp.ui.view@default:default,org.eclipse.emf.ecp.ui@default:default,org.eclipse.emf.ecp.view.compoundcontrol.model@default:default,org.eclipse.emf.ecp.view.compoundcontrol.swt.test@default:false,org.eclipse.emf.ecp.view.compoundcontrol.swt@default:default,org.eclipse.emf.ecp.view.compoundcontrol.tooling@default:default,org.eclipse.emf.ecp.view.context@default:default,org.eclipse.emf.ecp.view.core.swt@default:default,org.eclipse.emf.ecp.view.model.common@default:default,org.eclipse.emf.ecp.view.model@default:default,org.eclipse.emf.ecp.view.swt.layout@default:default,org.eclipse.emf.ecp.view.template.model@default:default,org.eclipse.emf.ecp.view.test.common@default:default,org.eclipse.emf.ecp.view.util.swt@default:default,org.eclipse.emf.ecp.view.validation@default:default,org.eclipse.emf.ecp.view.vertical.model@default:default,org.eclipse.emfforms.common.prevalidation@default:default,org.eclipse.emfforms.common.validation.tests@default:false,org.eclipse.emfforms.common.validation@default:default,org.eclipse.emfforms.common@default:default,org.eclipse.emfforms.core.services.databinding.testmodel@default:default,org.eclipse.emfforms.core.services.editsupport@default:default,org.eclipse.emfforms.core.services.emf@default:default,org.eclipse.emfforms.core.services.emfspecificservice@default:default,org.eclipse.emfforms.core.services.legacy.tests@default:false,org.eclipse.emfforms.core.services.legacy@default:default,org.eclipse.emfforms.core.services.structuralchange.default@default:default,org.eclipse.emfforms.core.services.structuralchange@default:default,org.eclipse.emfforms.core.services.tests@default:false,org.eclipse.emfforms.core.services@default:default,org.eclipse.emfforms.localization@default:default,org.eclipse.emfforms.swt.common.test@default:default,org.eclipse.emfforms.swt.control.text.richtext@default:default,org.eclipse.emfforms.swt.core.di@default:default,org.eclipse.emfforms.swt.core@default:default"/> +<stringAttribute key="selected_target_plugins" value="com.ibm.icu@default:default,javax.annotation@default:default,javax.inject@default:default,javax.servlet@default:default,org.apache.ant@default:default,org.apache.batik.css*1.7.0.v201011041433@default:default,org.apache.batik.util*1.7.0.v201011041433@default:default,org.apache.batik.util.gui*1.7.0.v200903091627@default:default,org.apache.commons.codec@default:default,org.apache.commons.jxpath@default:default,org.apache.commons.logging@default:default,org.apache.felix.scr@default:default,org.eclipse.ant.core@default:default,org.eclipse.compare.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding*1.5.0.v20150422-0725@default:default,org.eclipse.core.databinding*1.6.100.v20170515-1119@default:default,org.eclipse.core.databinding.observable*1.5.0.v20150422-0725@default:default,org.eclipse.core.databinding.observable*1.6.100.v20170515-1119@default:default,org.eclipse.core.databinding.property*1.5.0.v20150422-0725@default:default,org.eclipse.core.databinding.property*1.6.100.v20170515-1119@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.resources@default:default,org.eclipse.core.runtime@default:true,org.eclipse.core.variables@default:default,org.eclipse.e4.core.commands@default:default,org.eclipse.e4.core.contexts@default:default,org.eclipse.e4.core.di.annotations@default:default,org.eclipse.e4.core.di.extensions.supplier@default:default,org.eclipse.e4.core.di.extensions@default:default,org.eclipse.e4.core.di@default:default,org.eclipse.e4.core.services@default:default,org.eclipse.e4.emf.xpath@default:default,org.eclipse.e4.ui.bindings@default:default,org.eclipse.e4.ui.css.core@default:default,org.eclipse.e4.ui.css.swt.theme@default:default,org.eclipse.e4.ui.css.swt@default:default,org.eclipse.e4.ui.di@default:default,org.eclipse.e4.ui.model.workbench@default:default,org.eclipse.e4.ui.services@default:default,org.eclipse.e4.ui.widgets@default:default,org.eclipse.e4.ui.workbench.addons.swt@default:default,org.eclipse.e4.ui.workbench.renderers.swt@default:default,org.eclipse.e4.ui.workbench.swt@default:default,org.eclipse.e4.ui.workbench3@default:default,org.eclipse.e4.ui.workbench@default:default,org.eclipse.emf.common.ui@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.databinding.edit@default:default,org.eclipse.emf.databinding@default:default,org.eclipse.emf.ecore.change@default:default,org.eclipse.emf.ecore.xmi@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.emf.edit.ui@default:default,org.eclipse.emf.edit@default:default,org.eclipse.emf.emfstore.client@default:default,org.eclipse.emf.emfstore.common.model@default:default,org.eclipse.emf.emfstore.common@default:default,org.eclipse.emf.emfstore.examplemodel.edit@default:default,org.eclipse.emf.emfstore.examplemodel@default:default,org.eclipse.emf.emfstore.migration@default:default,org.eclipse.emf.emfstore.server.model@default:default,org.eclipse.emf.emfstore.server@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.bidi@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.event@default:default,org.eclipse.equinox.p2.core@default:default,org.eclipse.equinox.p2.engine@default:default,org.eclipse.equinox.p2.metadata.repository@default:default,org.eclipse.equinox.p2.metadata@default:default,org.eclipse.equinox.p2.repository@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.region@default:false,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.security@default:default,org.eclipse.equinox.transforms.hook@default:false,org.eclipse.equinox.util@default:default,org.eclipse.equinox.weaving.hook@default:false,org.eclipse.help@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.jface.text@default:default,org.eclipse.jface@default:default,org.eclipse.net4j.util@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services@default:default,org.eclipse.osgi.util@default:default,org.eclipse.osgi@-1:true,org.eclipse.swt.gtk.linux.x86_64@default:false,org.eclipse.swt@default:default,org.eclipse.swtbot.ant.junit@default:false,org.eclipse.team.core@default:default,org.eclipse.text@default:default,org.eclipse.ui.forms@default:default,org.eclipse.ui.ide@default:default,org.eclipse.ui.trace@default:default,org.eclipse.ui.views@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.ui@default:default,org.eclipse.update.configurator@3:true,org.hamcrest.core@default:default,org.junit@default:default,org.mockito.mockito-core-hamcrest-modified@default:default,org.objenesis@default:default,org.tukaani.xz@default:default,org.w3c.css.sac@default:default,org.w3c.dom.events@default:default,org.w3c.dom.smil*1.0.1.v200903091627@default:default,org.w3c.dom.svg@default:default"/> +<stringAttribute key="selected_workspace_plugins" value="org.eclipse.emf.ecp.common.ui@default:default,org.eclipse.emf.ecp.common@default:default,org.eclipse.emf.ecp.core@default:default,org.eclipse.emf.ecp.edit.swt@default:default,org.eclipse.emf.ecp.edit@default:default,org.eclipse.emf.ecp.emfstore.core@default:default,org.eclipse.emf.ecp.makeithappen.model@default:default,org.eclipse.emf.ecp.test.common@default:default,org.eclipse.emf.ecp.ui.view.swt@default:default,org.eclipse.emf.ecp.ui.view@default:default,org.eclipse.emf.ecp.ui@default:default,org.eclipse.emf.ecp.view.compoundcontrol.model@default:default,org.eclipse.emf.ecp.view.compoundcontrol.swt.test@default:false,org.eclipse.emf.ecp.view.compoundcontrol.swt@default:default,org.eclipse.emf.ecp.view.compoundcontrol.tooling@default:default,org.eclipse.emf.ecp.view.context@default:default,org.eclipse.emf.ecp.view.core.swt@default:default,org.eclipse.emf.ecp.view.model.common@default:default,org.eclipse.emf.ecp.view.model@default:default,org.eclipse.emf.ecp.view.swt.layout@default:default,org.eclipse.emf.ecp.view.template.model@default:default,org.eclipse.emf.ecp.view.test.common@default:default,org.eclipse.emf.ecp.view.util.swt@default:default,org.eclipse.emf.ecp.view.validation@default:default,org.eclipse.emf.ecp.view.vertical.model@default:default,org.eclipse.emfforms.common.prevalidation@default:default,org.eclipse.emfforms.common.validation.tests@default:false,org.eclipse.emfforms.common.validation@default:default,org.eclipse.emfforms.common@default:default,org.eclipse.emfforms.core.bazaar@default:default,org.eclipse.emfforms.core.services.databinding.testmodel@default:default,org.eclipse.emfforms.core.services.editsupport@default:default,org.eclipse.emfforms.core.services.emf@default:default,org.eclipse.emfforms.core.services.emfspecificservice@default:default,org.eclipse.emfforms.core.services.legacy.tests@default:false,org.eclipse.emfforms.core.services.legacy@default:default,org.eclipse.emfforms.core.services.structuralchange.default@default:default,org.eclipse.emfforms.core.services.structuralchange@default:default,org.eclipse.emfforms.core.services.tests@default:false,org.eclipse.emfforms.core.services@default:default,org.eclipse.emfforms.localization@default:default,org.eclipse.emfforms.swt.common.test@default:default,org.eclipse.emfforms.swt.control.text.richtext@default:default,org.eclipse.emfforms.swt.core.di@default:default,org.eclipse.emfforms.swt.core@default:default"/> <booleanAttribute key="show_selected_only" value="false"/> <booleanAttribute key="tracing" value="false"/> <booleanAttribute key="useCustomFeatures" value="false"/> diff --git a/tests/org.eclipse.emf.ecp.view.compoundcontrol.swt.test/src/org/eclipse/emf/ecp/view/spi/compoundcontrol/swt/CompoundControlSWTRenderer_ITest.java b/tests/org.eclipse.emf.ecp.view.compoundcontrol.swt.test/src/org/eclipse/emf/ecp/view/spi/compoundcontrol/swt/CompoundControlSWTRenderer_ITest.java index 6e20748ec7..e71aab5059 100644 --- a/tests/org.eclipse.emf.ecp.view.compoundcontrol.swt.test/src/org/eclipse/emf/ecp/view/spi/compoundcontrol/swt/CompoundControlSWTRenderer_ITest.java +++ b/tests/org.eclipse.emf.ecp.view.compoundcontrol.swt.test/src/org/eclipse/emf/ecp/view/spi/compoundcontrol/swt/CompoundControlSWTRenderer_ITest.java @@ -13,6 +13,7 @@ package org.eclipse.emf.ecp.view.spi.compoundcontrol.swt; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; @@ -28,7 +29,9 @@ import java.util.Set; import org.eclipse.core.databinding.observable.Observables; import org.eclipse.emf.common.util.ECollections; +import org.eclipse.emf.databinding.IEMFValueProperty; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecp.test.common.DefaultRealm; import org.eclipse.emf.ecp.view.spi.compoundcontrol.model.VCompoundControl; import org.eclipse.emf.ecp.view.spi.context.ViewModelContext; @@ -46,7 +49,11 @@ import org.eclipse.emf.ecp.view.template.style.alignment.model.VTAlignmentFactor import org.eclipse.emf.ecp.view.template.style.alignment.model.VTControlLabelAlignmentStyleProperty; import org.eclipse.emf.ecp.view.template.style.labelwidth.model.VTLabelWidthStyleProperty; import org.eclipse.emf.ecp.view.template.style.labelwidth.model.VTLabelwidthFactory; +import org.eclipse.emf.ecp.view.template.style.wrap.model.VTLabelWrapStyleProperty; +import org.eclipse.emf.ecp.view.template.style.wrap.model.VTWrapFactory; import org.eclipse.emfforms.spi.common.report.ReportService; +import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException; +import org.eclipse.emfforms.spi.core.services.databinding.emf.EMFFormsDatabindingEMF; import org.eclipse.emfforms.spi.core.services.label.EMFFormsLabelProvider; import org.eclipse.emfforms.spi.core.services.label.NoLabelFoundException; import org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer; @@ -58,7 +65,6 @@ import org.eclipse.emfforms.spi.swt.core.layout.SWTGridDescription; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; @@ -74,6 +80,9 @@ public class CompoundControlSWTRenderer_ITest { private static final String LABEL1 = "label1"; //$NON-NLS-1$ private static final String LABEL2 = "label2"; //$NON-NLS-1$ + private static final String TOOLTIP1 = "tooltip1"; //$NON-NLS-1$ + private static final String TOOLTIP2 = "tooltip2"; //$NON-NLS-1$ + private static final String C_CONTROL = "CControl"; //$NON-NLS-1$ private static final String C_VALIDATION = "CValidation"; //$NON-NLS-1$ @@ -85,6 +94,7 @@ public class CompoundControlSWTRenderer_ITest { private VTViewTemplateProvider viewTemplateProvider; private Shell shell; private DefaultRealm realm; + private EMFFormsDatabindingEMF emfFormsDatabindingEMF; @Before public void before() { @@ -96,6 +106,7 @@ public class CompoundControlSWTRenderer_ITest { emfFormsLabelProvider = mock(EMFFormsLabelProvider.class); emfFormsRendererFactory = mock(EMFFormsRendererFactory.class); viewTemplateProvider = Mockito.mock(VTViewTemplateProvider.class); + emfFormsDatabindingEMF = Mockito.mock(EMFFormsDatabindingEMF.class); } @After @@ -106,7 +117,7 @@ public class CompoundControlSWTRenderer_ITest { private CompoundControlSWTRenderer createRenderer() { return new CompoundControlSWTRenderer(compoundControl, viewModelContext, reportService, emfFormsLabelProvider, - emfFormsRendererFactory, viewTemplateProvider); + emfFormsRendererFactory, viewTemplateProvider, emfFormsDatabindingEMF); } @Test @@ -123,35 +134,48 @@ public class CompoundControlSWTRenderer_ITest { @Test public void testGetGridDescription() { + when(compoundControl.getLabelAlignment()).thenReturn(LabelAlignment.DEFAULT); + final CompoundControlSWTRenderer renderer = createRenderer(); final SWTGridDescription gridDescription = renderer.getGridDescription(mock(SWTGridDescription.class)); - assertEquals(2, gridDescription.getColumns()); + assertEquals(3, gridDescription.getColumns()); assertEquals(1, gridDescription.getRows()); - assertEquals(2, gridDescription.getGrid().size()); + assertEquals(3, gridDescription.getGrid().size()); final SWTGridCell label = gridDescription.getGrid().get(0); assertEquals(0, label.getColumn()); assertEquals(1, label.getHorizontalSpan()); assertEquals(0, label.getRow()); assertSame(renderer, label.getRenderer()); - assertTrue(label.isHorizontalFill()); + assertFalse(label.isHorizontalFill()); assertFalse(label.isHorizontalGrab()); assertFalse(label.isVerticalFill()); assertFalse(label.isVerticalGrab()); - final SWTGridCell controls = gridDescription.getGrid().get(1); - assertEquals(1, controls.getColumn()); + final SWTGridCell validation = gridDescription.getGrid().get(1); + assertEquals(1, validation.getColumn()); + assertEquals(1, validation.getHorizontalSpan()); + assertEquals(0, validation.getRow()); + assertSame(renderer, validation.getRenderer()); + assertFalse(validation.isHorizontalFill()); + assertFalse(validation.isHorizontalGrab()); + assertFalse(validation.isVerticalFill()); + assertFalse(validation.isVerticalGrab()); + + final SWTGridCell controls = gridDescription.getGrid().get(2); + assertEquals(2, controls.getColumn()); assertEquals(1, controls.getHorizontalSpan()); assertEquals(0, controls.getRow()); assertSame(renderer, controls.getRenderer()); assertTrue(controls.isHorizontalFill()); assertTrue(controls.isHorizontalGrab()); - assertFalse(controls.isVerticalFill()); + assertTrue(controls.isVerticalFill()); assertFalse(controls.isVerticalGrab()); } @Test public void testGetGridDescriptionWithWidth() { + when(compoundControl.getLabelAlignment()).thenReturn(LabelAlignment.DEFAULT); final VTLabelWidthStyleProperty property = VTLabelwidthFactory.eINSTANCE.createLabelWidthStyleProperty(); property.setWidth(11); @@ -160,22 +184,148 @@ public class CompoundControlSWTRenderer_ITest { final CompoundControlSWTRenderer renderer = createRenderer(); final SWTGridDescription gridDescription = renderer.getGridDescription(mock(SWTGridDescription.class)); - assertEquals(2, gridDescription.getColumns()); + assertEquals(3, gridDescription.getColumns()); assertEquals(1, gridDescription.getRows()); - assertEquals(2, gridDescription.getGrid().size()); + assertEquals(3, gridDescription.getGrid().size()); final SWTGridCell label = gridDescription.getGrid().get(0); assertEquals(0, label.getColumn()); assertEquals(1, label.getHorizontalSpan()); assertEquals(0, label.getRow()); assertSame(renderer, label.getRenderer()); - assertTrue(label.isHorizontalFill()); + assertFalse(label.isHorizontalFill()); assertFalse(label.isHorizontalGrab()); assertFalse(label.isVerticalFill()); assertFalse(label.isVerticalGrab()); assertEquals(11, label.getPreferredSize().x); assertEquals(SWT.DEFAULT, label.getPreferredSize().y); + final SWTGridCell validation = gridDescription.getGrid().get(1); + assertEquals(1, validation.getColumn()); + assertEquals(1, validation.getHorizontalSpan()); + assertEquals(0, validation.getRow()); + assertSame(renderer, validation.getRenderer()); + assertFalse(validation.isHorizontalFill()); + assertFalse(validation.isHorizontalGrab()); + assertFalse(validation.isVerticalFill()); + assertFalse(validation.isVerticalGrab()); + + final SWTGridCell controls = gridDescription.getGrid().get(2); + assertEquals(2, controls.getColumn()); + assertEquals(1, controls.getHorizontalSpan()); + assertEquals(0, controls.getRow()); + assertSame(renderer, controls.getRenderer()); + assertTrue(controls.isHorizontalFill()); + assertTrue(controls.isHorizontalGrab()); + assertTrue(controls.isVerticalFill()); + assertFalse(controls.isVerticalGrab()); + } + + @Test + public void testGetGridDescriptionControlLabelAlignmentLeft() { + when(compoundControl.getLabelAlignment()).thenReturn(LabelAlignment.LEFT); + + final CompoundControlSWTRenderer renderer = createRenderer(); + final SWTGridDescription gridDescription = renderer.getGridDescription(mock(SWTGridDescription.class)); + assertEquals(3, gridDescription.getColumns()); + assertEquals(1, gridDescription.getRows()); + assertEquals(3, gridDescription.getGrid().size()); + + final SWTGridCell label = gridDescription.getGrid().get(0); + assertEquals(0, label.getColumn()); + assertEquals(1, label.getHorizontalSpan()); + assertEquals(0, label.getRow()); + assertSame(renderer, label.getRenderer()); + assertFalse(label.isHorizontalFill()); + assertFalse(label.isHorizontalGrab()); + assertFalse(label.isVerticalFill()); + assertFalse(label.isVerticalGrab()); + + final SWTGridCell validation = gridDescription.getGrid().get(1); + assertEquals(1, validation.getColumn()); + assertEquals(1, validation.getHorizontalSpan()); + assertEquals(0, validation.getRow()); + assertSame(renderer, validation.getRenderer()); + assertFalse(validation.isHorizontalFill()); + assertFalse(validation.isHorizontalGrab()); + assertFalse(validation.isVerticalFill()); + assertFalse(validation.isVerticalGrab()); + + final SWTGridCell controls = gridDescription.getGrid().get(2); + assertEquals(2, controls.getColumn()); + assertEquals(1, controls.getHorizontalSpan()); + assertEquals(0, controls.getRow()); + assertSame(renderer, controls.getRenderer()); + assertTrue(controls.isHorizontalFill()); + assertTrue(controls.isHorizontalGrab()); + assertTrue(controls.isVerticalFill()); + assertFalse(controls.isVerticalGrab()); + } + + @Test + public void testGetGridDescriptionControlLabelAlignmentTop() { + when(compoundControl.getLabelAlignment()).thenReturn(LabelAlignment.TOP); + + final CompoundControlSWTRenderer renderer = createRenderer(); + final SWTGridDescription gridDescription = renderer.getGridDescription(mock(SWTGridDescription.class)); + assertEquals(3, gridDescription.getColumns()); + assertEquals(1, gridDescription.getRows()); + assertEquals(3, gridDescription.getGrid().size()); + + final SWTGridCell label = gridDescription.getGrid().get(0); + assertEquals(0, label.getColumn()); + assertEquals(1, label.getHorizontalSpan()); + assertEquals(0, label.getRow()); + assertSame(renderer, label.getRenderer()); + assertFalse(label.isHorizontalFill()); + assertFalse(label.isHorizontalGrab()); + assertFalse(label.isVerticalFill()); + assertFalse(label.isVerticalGrab()); + + final SWTGridCell validation = gridDescription.getGrid().get(1); + assertEquals(1, validation.getColumn()); + assertEquals(1, validation.getHorizontalSpan()); + assertEquals(0, validation.getRow()); + assertSame(renderer, validation.getRenderer()); + assertFalse(validation.isHorizontalFill()); + assertFalse(validation.isHorizontalGrab()); + assertFalse(validation.isVerticalFill()); + assertFalse(validation.isVerticalGrab()); + + final SWTGridCell controls = gridDescription.getGrid().get(2); + assertEquals(2, controls.getColumn()); + assertEquals(1, controls.getHorizontalSpan()); + assertEquals(0, controls.getRow()); + assertSame(renderer, controls.getRenderer()); + assertTrue(controls.isHorizontalFill()); + assertTrue(controls.isHorizontalGrab()); + assertTrue(controls.isVerticalFill()); + assertFalse(controls.isVerticalGrab()); + + /* assert that top was set to default because not supported */ + verify(compoundControl, times(1)).setLabelAlignment(LabelAlignment.DEFAULT); + } + + @Test + public void testGetGridDescriptionControlLabelAlignmentNone() { + when(compoundControl.getLabelAlignment()).thenReturn(LabelAlignment.NONE); + + final CompoundControlSWTRenderer renderer = createRenderer(); + final SWTGridDescription gridDescription = renderer.getGridDescription(mock(SWTGridDescription.class)); + assertEquals(2, gridDescription.getColumns()); + assertEquals(1, gridDescription.getRows()); + assertEquals(2, gridDescription.getGrid().size()); + + final SWTGridCell validation = gridDescription.getGrid().get(0); + assertEquals(0, validation.getColumn()); + assertEquals(1, validation.getHorizontalSpan()); + assertEquals(0, validation.getRow()); + assertSame(renderer, validation.getRenderer()); + assertFalse(validation.isHorizontalFill()); + assertFalse(validation.isHorizontalGrab()); + assertFalse(validation.isVerticalFill()); + assertFalse(validation.isVerticalGrab()); + final SWTGridCell controls = gridDescription.getGrid().get(1); assertEquals(1, controls.getColumn()); assertEquals(1, controls.getHorizontalSpan()); @@ -183,12 +333,12 @@ public class CompoundControlSWTRenderer_ITest { assertSame(renderer, controls.getRenderer()); assertTrue(controls.isHorizontalFill()); assertTrue(controls.isHorizontalGrab()); - assertFalse(controls.isVerticalFill()); + assertTrue(controls.isVerticalFill()); assertFalse(controls.isVerticalGrab()); } @Test - public void testCreateLabel() throws NoLabelFoundException { + public void testCreateLabel() throws NoLabelFoundException, DatabindingFailedException { /* setup */ final VControl control1 = mock(VControl.class); final VFeaturePathDomainModelReference dmr1 = mock(VFeaturePathDomainModelReference.class); @@ -209,25 +359,36 @@ public class CompoundControlSWTRenderer_ITest { when(emfFormsLabelProvider.getDisplayName(dmr2, domainModel)) .thenReturn(Observables.constantObservableValue(LABEL2, String.class)); + when(emfFormsLabelProvider.getDescription(dmr1, domainModel)) + .thenReturn(Observables.constantObservableValue(TOOLTIP1, String.class)); + + when(emfFormsLabelProvider.getDescription(dmr2, domainModel)) + .thenReturn(Observables.constantObservableValue(TOOLTIP2, String.class)); + + final IEMFValueProperty valueProperty1 = mock(IEMFValueProperty.class); + when(emfFormsDatabindingEMF.getValueProperty(dmr1, domainModel)).thenReturn(valueProperty1); + final EStructuralFeature structuralFeature1 = mock(EStructuralFeature.class); + when(valueProperty1.getStructuralFeature()).thenReturn(structuralFeature1); + + final IEMFValueProperty valueProperty2 = mock(IEMFValueProperty.class); + when(emfFormsDatabindingEMF.getValueProperty(dmr2, domainModel)).thenReturn(valueProperty2); + final EStructuralFeature structuralFeature2 = mock(EStructuralFeature.class); + when(valueProperty2.getStructuralFeature()).thenReturn(structuralFeature2); + final CompoundControlSWTRenderer renderer = createRenderer(); /* act */ final Control label = renderer.createLabel(shell); /* assert */ - assertTrue(Composite.class.isInstance(label)); - final Composite labelComposite = Composite.class.cast(label); - assertEquals(3, labelComposite.getChildren().length); - for (final Control control : labelComposite.getChildren()) { - assertTrue(Label.class.isInstance(control)); - } - assertEquals(LABEL1, Label.class.cast(labelComposite.getChildren()[0]).getText()); - assertEquals("/", Label.class.cast(labelComposite.getChildren()[1]).getText()); //$NON-NLS-1$ - assertEquals(LABEL2, Label.class.cast(labelComposite.getChildren()[2]).getText()); + assertTrue(Label.class.isInstance(label)); + final Label labelComposite = Label.class.cast(label); + assertEquals(LABEL1 + " / " + LABEL2, labelComposite.getText()); //$NON-NLS-1$ + assertEquals(TOOLTIP1 + "\n" + TOOLTIP2, labelComposite.getToolTipText()); //$NON-NLS-1$ } @Test - public void testCreateLabelAlignmentDefault() throws NoLabelFoundException { + public void testCreateLabelAlignmentDefault() throws NoLabelFoundException, DatabindingFailedException { /* setup */ final VControl control1 = mock(VControl.class); final VFeaturePathDomainModelReference dmr1 = mock(VFeaturePathDomainModelReference.class); @@ -248,23 +409,34 @@ public class CompoundControlSWTRenderer_ITest { when(emfFormsLabelProvider.getDisplayName(dmr2, domainModel)) .thenReturn(Observables.constantObservableValue(LABEL2, String.class)); + when(emfFormsLabelProvider.getDescription(dmr1, domainModel)) + .thenReturn(Observables.constantObservableValue(TOOLTIP1, String.class)); + + when(emfFormsLabelProvider.getDescription(dmr2, domainModel)) + .thenReturn(Observables.constantObservableValue(TOOLTIP2, String.class)); + + final IEMFValueProperty valueProperty1 = mock(IEMFValueProperty.class); + when(emfFormsDatabindingEMF.getValueProperty(dmr1, domainModel)).thenReturn(valueProperty1); + final EStructuralFeature structuralFeature1 = mock(EStructuralFeature.class); + when(valueProperty1.getStructuralFeature()).thenReturn(structuralFeature1); + + final IEMFValueProperty valueProperty2 = mock(IEMFValueProperty.class); + when(emfFormsDatabindingEMF.getValueProperty(dmr2, domainModel)).thenReturn(valueProperty2); + final EStructuralFeature structuralFeature2 = mock(EStructuralFeature.class); + when(valueProperty2.getStructuralFeature()).thenReturn(structuralFeature2); + final CompoundControlSWTRenderer renderer = createRenderer(); /* act */ final Control label = renderer.createLabel(shell); /* assert */ - final Composite labelComposite = Composite.class.cast(label); - assertFalse(GridData.class.cast(labelComposite.getChildren()[0].getLayoutData()).grabExcessHorizontalSpace); - assertFalse(GridData.class.cast(labelComposite.getChildren()[1].getLayoutData()).grabExcessHorizontalSpace); - assertTrue(GridData.class.cast(labelComposite.getChildren()[2].getLayoutData()).grabExcessHorizontalSpace); - assertEquals(SWT.LEFT, Label.class.cast(labelComposite.getChildren()[0]).getAlignment()); - assertEquals(SWT.LEFT, Label.class.cast(labelComposite.getChildren()[1]).getAlignment()); - assertEquals(SWT.LEFT, Label.class.cast(labelComposite.getChildren()[2]).getAlignment()); + final Label swtLabel = Label.class.cast(label); + assertEquals(SWT.LEFT, swtLabel.getAlignment()); } @Test - public void testCreateLabelAlignmentLeft() throws NoLabelFoundException { + public void testCreateLabelAlignmentLeft() throws NoLabelFoundException, DatabindingFailedException { /* setup */ final VControl control1 = mock(VControl.class); final VFeaturePathDomainModelReference dmr1 = mock(VFeaturePathDomainModelReference.class); @@ -285,6 +457,21 @@ public class CompoundControlSWTRenderer_ITest { when(emfFormsLabelProvider.getDisplayName(dmr2, domainModel)) .thenReturn(Observables.constantObservableValue(LABEL2, String.class)); + when(emfFormsLabelProvider.getDescription(dmr1, domainModel)) + .thenReturn(Observables.constantObservableValue(TOOLTIP1, String.class)); + + when(emfFormsLabelProvider.getDescription(dmr2, domainModel)) + .thenReturn(Observables.constantObservableValue(TOOLTIP2, String.class)); + + final IEMFValueProperty valueProperty1 = mock(IEMFValueProperty.class); + when(emfFormsDatabindingEMF.getValueProperty(dmr1, domainModel)).thenReturn(valueProperty1); + final EStructuralFeature structuralFeature1 = mock(EStructuralFeature.class); + when(valueProperty1.getStructuralFeature()).thenReturn(structuralFeature1); + + final IEMFValueProperty valueProperty2 = mock(IEMFValueProperty.class); + when(emfFormsDatabindingEMF.getValueProperty(dmr2, domainModel)).thenReturn(valueProperty2); + final EStructuralFeature structuralFeature2 = mock(EStructuralFeature.class); + final CompoundControlSWTRenderer renderer = createRenderer(); final VTControlLabelAlignmentStyleProperty property = VTAlignmentFactory.eINSTANCE @@ -292,22 +479,18 @@ public class CompoundControlSWTRenderer_ITest { property.setType(AlignmentType.LEFT); final Set<VTStyleProperty> properties = Collections.<VTStyleProperty> singleton(property); Mockito.when(viewTemplateProvider.getStyleProperties(compoundControl, viewModelContext)).thenReturn(properties); + when(valueProperty2.getStructuralFeature()).thenReturn(structuralFeature2); /* act */ final Control label = renderer.createLabel(shell); /* assert */ - final Composite labelComposite = Composite.class.cast(label); - assertFalse(GridData.class.cast(labelComposite.getChildren()[0].getLayoutData()).grabExcessHorizontalSpace); - assertFalse(GridData.class.cast(labelComposite.getChildren()[1].getLayoutData()).grabExcessHorizontalSpace); - assertTrue(GridData.class.cast(labelComposite.getChildren()[2].getLayoutData()).grabExcessHorizontalSpace); - assertEquals(SWT.LEFT, Label.class.cast(labelComposite.getChildren()[0]).getAlignment()); - assertEquals(SWT.LEFT, Label.class.cast(labelComposite.getChildren()[1]).getAlignment()); - assertEquals(SWT.LEFT, Label.class.cast(labelComposite.getChildren()[2]).getAlignment()); + final Label swtLabel = Label.class.cast(label); + assertEquals(SWT.LEFT, swtLabel.getAlignment()); } @Test - public void testCreateLabelAlignmentRight() throws NoLabelFoundException { + public void testCreateLabelAlignmentRight() throws NoLabelFoundException, DatabindingFailedException { /* setup */ final VControl control1 = mock(VControl.class); final VFeaturePathDomainModelReference dmr1 = mock(VFeaturePathDomainModelReference.class); @@ -328,6 +511,22 @@ public class CompoundControlSWTRenderer_ITest { when(emfFormsLabelProvider.getDisplayName(dmr2, domainModel)) .thenReturn(Observables.constantObservableValue(LABEL2, String.class)); + when(emfFormsLabelProvider.getDescription(dmr1, domainModel)) + .thenReturn(Observables.constantObservableValue(TOOLTIP1, String.class)); + + when(emfFormsLabelProvider.getDescription(dmr2, domainModel)) + .thenReturn(Observables.constantObservableValue(TOOLTIP2, String.class)); + + final IEMFValueProperty valueProperty1 = mock(IEMFValueProperty.class); + when(emfFormsDatabindingEMF.getValueProperty(dmr1, domainModel)).thenReturn(valueProperty1); + final EStructuralFeature structuralFeature1 = mock(EStructuralFeature.class); + when(valueProperty1.getStructuralFeature()).thenReturn(structuralFeature1); + + final IEMFValueProperty valueProperty2 = mock(IEMFValueProperty.class); + when(emfFormsDatabindingEMF.getValueProperty(dmr2, domainModel)).thenReturn(valueProperty2); + final EStructuralFeature structuralFeature2 = mock(EStructuralFeature.class); + when(valueProperty2.getStructuralFeature()).thenReturn(structuralFeature2); + final CompoundControlSWTRenderer renderer = createRenderer(); final VTControlLabelAlignmentStyleProperty property = VTAlignmentFactory.eINSTANCE @@ -340,13 +539,272 @@ public class CompoundControlSWTRenderer_ITest { final Control label = renderer.createLabel(shell); /* assert */ - final Composite labelComposite = Composite.class.cast(label); - assertTrue(GridData.class.cast(labelComposite.getChildren()[0].getLayoutData()).grabExcessHorizontalSpace); - assertFalse(GridData.class.cast(labelComposite.getChildren()[1].getLayoutData()).grabExcessHorizontalSpace); - assertFalse(GridData.class.cast(labelComposite.getChildren()[2].getLayoutData()).grabExcessHorizontalSpace); - assertEquals(SWT.RIGHT, Label.class.cast(labelComposite.getChildren()[0]).getAlignment()); - assertEquals(SWT.LEFT, Label.class.cast(labelComposite.getChildren()[1]).getAlignment()); - assertEquals(SWT.LEFT, Label.class.cast(labelComposite.getChildren()[2]).getAlignment()); + final Label swtLabel = Label.class.cast(label); + assertEquals(SWT.RIGHT, swtLabel.getAlignment()); + } + + // TODO + @Test + public void testCreateLabelWrapDefault() throws NoLabelFoundException, DatabindingFailedException { + /* setup */ + final VControl control1 = mock(VControl.class); + final VFeaturePathDomainModelReference dmr1 = mock(VFeaturePathDomainModelReference.class); + when(control1.getDomainModelReference()).thenReturn(dmr1); + + final VControl control2 = mock(VControl.class); + final VFeaturePathDomainModelReference dmr2 = mock(VFeaturePathDomainModelReference.class); + when(control2.getDomainModelReference()).thenReturn(dmr2); + + when(compoundControl.getControls()).thenReturn(ECollections.asEList(control1, control2)); + + final EObject domainModel = mock(EObject.class); + when(viewModelContext.getDomainModel()).thenReturn(domainModel); + + when(emfFormsLabelProvider.getDisplayName(dmr1, domainModel)) + .thenReturn(Observables.constantObservableValue(LABEL1, String.class)); + + when(emfFormsLabelProvider.getDisplayName(dmr2, domainModel)) + .thenReturn(Observables.constantObservableValue(LABEL2, String.class)); + + when(emfFormsLabelProvider.getDescription(dmr1, domainModel)) + .thenReturn(Observables.constantObservableValue(TOOLTIP1, String.class)); + + when(emfFormsLabelProvider.getDescription(dmr2, domainModel)) + .thenReturn(Observables.constantObservableValue(TOOLTIP2, String.class)); + + final IEMFValueProperty valueProperty1 = mock(IEMFValueProperty.class); + when(emfFormsDatabindingEMF.getValueProperty(dmr1, domainModel)).thenReturn(valueProperty1); + final EStructuralFeature structuralFeature1 = mock(EStructuralFeature.class); + when(valueProperty1.getStructuralFeature()).thenReturn(structuralFeature1); + + final IEMFValueProperty valueProperty2 = mock(IEMFValueProperty.class); + when(emfFormsDatabindingEMF.getValueProperty(dmr2, domainModel)).thenReturn(valueProperty2); + final EStructuralFeature structuralFeature2 = mock(EStructuralFeature.class); + when(valueProperty2.getStructuralFeature()).thenReturn(structuralFeature2); + + final CompoundControlSWTRenderer renderer = createRenderer(); + + /* act */ + final Control label = renderer.createLabel(shell); + + /* assert */ + final Label swtLabel = Label.class.cast(label); + assertEquals(0, swtLabel.getStyle() & SWT.WRAP); + } + + @Test + public void testCreateLabelWrapDisabled() throws NoLabelFoundException, DatabindingFailedException { + /* setup */ + final VControl control1 = mock(VControl.class); + final VFeaturePathDomainModelReference dmr1 = mock(VFeaturePathDomainModelReference.class); + when(control1.getDomainModelReference()).thenReturn(dmr1); + + final VControl control2 = mock(VControl.class); + final VFeaturePathDomainModelReference dmr2 = mock(VFeaturePathDomainModelReference.class); + when(control2.getDomainModelReference()).thenReturn(dmr2); + + when(compoundControl.getControls()).thenReturn(ECollections.asEList(control1, control2)); + + final EObject domainModel = mock(EObject.class); + when(viewModelContext.getDomainModel()).thenReturn(domainModel); + + when(emfFormsLabelProvider.getDisplayName(dmr1, domainModel)) + .thenReturn(Observables.constantObservableValue(LABEL1, String.class)); + + when(emfFormsLabelProvider.getDisplayName(dmr2, domainModel)) + .thenReturn(Observables.constantObservableValue(LABEL2, String.class)); + + when(emfFormsLabelProvider.getDescription(dmr1, domainModel)) + .thenReturn(Observables.constantObservableValue(TOOLTIP1, String.class)); + + when(emfFormsLabelProvider.getDescription(dmr2, domainModel)) + .thenReturn(Observables.constantObservableValue(TOOLTIP2, String.class)); + + final IEMFValueProperty valueProperty1 = mock(IEMFValueProperty.class); + when(emfFormsDatabindingEMF.getValueProperty(dmr1, domainModel)).thenReturn(valueProperty1); + final EStructuralFeature structuralFeature1 = mock(EStructuralFeature.class); + when(valueProperty1.getStructuralFeature()).thenReturn(structuralFeature1); + + final IEMFValueProperty valueProperty2 = mock(IEMFValueProperty.class); + when(emfFormsDatabindingEMF.getValueProperty(dmr2, domainModel)).thenReturn(valueProperty2); + final EStructuralFeature structuralFeature2 = mock(EStructuralFeature.class); + when(valueProperty2.getStructuralFeature()).thenReturn(structuralFeature2); + + final CompoundControlSWTRenderer renderer = createRenderer(); + + final VTLabelWrapStyleProperty property = VTWrapFactory.eINSTANCE.createLabelWrapStyleProperty(); + property.setWrapLabel(false); + final Set<VTStyleProperty> properties = Collections.<VTStyleProperty> singleton(property); + Mockito.when(viewTemplateProvider.getStyleProperties(compoundControl, viewModelContext)).thenReturn(properties); + when(valueProperty2.getStructuralFeature()).thenReturn(structuralFeature2); + + /* act */ + final Control label = renderer.createLabel(shell); + + /* assert */ + final Label swtLabel = Label.class.cast(label); + assertEquals(0, swtLabel.getStyle() & SWT.WRAP); + } + + @Test + public void testCreateLabelWrapEnabled() throws NoLabelFoundException, DatabindingFailedException { + /* setup */ + final VControl control1 = mock(VControl.class); + final VFeaturePathDomainModelReference dmr1 = mock(VFeaturePathDomainModelReference.class); + when(control1.getDomainModelReference()).thenReturn(dmr1); + + final VControl control2 = mock(VControl.class); + final VFeaturePathDomainModelReference dmr2 = mock(VFeaturePathDomainModelReference.class); + when(control2.getDomainModelReference()).thenReturn(dmr2); + + when(compoundControl.getControls()).thenReturn(ECollections.asEList(control1, control2)); + + final EObject domainModel = mock(EObject.class); + when(viewModelContext.getDomainModel()).thenReturn(domainModel); + + when(emfFormsLabelProvider.getDisplayName(dmr1, domainModel)) + .thenReturn(Observables.constantObservableValue(LABEL1, String.class)); + + when(emfFormsLabelProvider.getDisplayName(dmr2, domainModel)) + .thenReturn(Observables.constantObservableValue(LABEL2, String.class)); + + when(emfFormsLabelProvider.getDescription(dmr1, domainModel)) + .thenReturn(Observables.constantObservableValue(TOOLTIP1, String.class)); + + when(emfFormsLabelProvider.getDescription(dmr2, domainModel)) + .thenReturn(Observables.constantObservableValue(TOOLTIP2, String.class)); + + final IEMFValueProperty valueProperty1 = mock(IEMFValueProperty.class); + when(emfFormsDatabindingEMF.getValueProperty(dmr1, domainModel)).thenReturn(valueProperty1); + final EStructuralFeature structuralFeature1 = mock(EStructuralFeature.class); + when(valueProperty1.getStructuralFeature()).thenReturn(structuralFeature1); + + final IEMFValueProperty valueProperty2 = mock(IEMFValueProperty.class); + when(emfFormsDatabindingEMF.getValueProperty(dmr2, domainModel)).thenReturn(valueProperty2); + final EStructuralFeature structuralFeature2 = mock(EStructuralFeature.class); + when(valueProperty2.getStructuralFeature()).thenReturn(structuralFeature2); + + final CompoundControlSWTRenderer renderer = createRenderer(); + + final VTLabelWrapStyleProperty property = VTWrapFactory.eINSTANCE.createLabelWrapStyleProperty(); + property.setWrapLabel(true); + final Set<VTStyleProperty> properties = Collections.<VTStyleProperty> singleton(property); + Mockito.when(viewTemplateProvider.getStyleProperties(compoundControl, viewModelContext)).thenReturn(properties); + when(valueProperty2.getStructuralFeature()).thenReturn(structuralFeature2); + + /* act */ + final Control label = renderer.createLabel(shell); + + /* assert */ + final Label swtLabel = Label.class.cast(label); + assertNotEquals(0, swtLabel.getStyle() & SWT.WRAP); + } + + @Test + public void testCreateValidationIconNoChildren() + throws NoRendererFoundException, NoPropertyDescriptorFoundExeption { + /* setup */ + when(compoundControl.getControls()).thenReturn(ECollections.<VControl> emptyEList()); + + final EObject domainModel = mock(EObject.class); + when(viewModelContext.getDomainModel()).thenReturn(domainModel); + + final CompoundControlSWTRenderer renderer = spy(createRenderer()); + + /* act */ + final Control label = renderer.createValidationIcon(shell); + + /* assert */ + verify(renderer, times(1)).createDummyValidationIcon(shell); + assertTrue(Label.class.isInstance(label)); + } + + @Test + public void testCreateValidationIconFirstCellHasNoRenderer() + throws NoRendererFoundException, NoPropertyDescriptorFoundExeption { + /* setup */ + final VControl control1 = mock(VControl.class); + final VFeaturePathDomainModelReference dmr1 = mock(VFeaturePathDomainModelReference.class); + when(control1.getDomainModelReference()).thenReturn(dmr1); + + final VControl control2 = mock(VControl.class); + final VFeaturePathDomainModelReference dmr2 = mock(VFeaturePathDomainModelReference.class); + when(control2.getDomainModelReference()).thenReturn(dmr2); + + when(compoundControl.getControls()).thenReturn(ECollections.asEList(control1, control2)); + + final EObject domainModel = mock(EObject.class); + when(viewModelContext.getDomainModel()).thenReturn(domainModel); + + final CompoundControlSWTRenderer renderer = spy(createRenderer()); + + /* act */ + final Control label = renderer.createValidationIcon(shell); + + /* assert */ + verify(renderer, times(1)).createDummyValidationIcon(shell); + assertTrue(Label.class.isInstance(label)); + } + + @Test + public void testCreateValidationIconFirstCellRenderer1Column() + throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, EMFFormsNoRendererException { + /* setup */ + final VControl control1 = mock(VControl.class); + final VFeaturePathDomainModelReference dmr1 = mock(VFeaturePathDomainModelReference.class); + when(control1.getDomainModelReference()).thenReturn(dmr1); + + final VControl control2 = mock(VControl.class); + final VFeaturePathDomainModelReference dmr2 = mock(VFeaturePathDomainModelReference.class); + when(control2.getDomainModelReference()).thenReturn(dmr2); + + when(compoundControl.getControls()).thenReturn(ECollections.asEList(control1, control2)); + + final EObject domainModel = mock(EObject.class); + when(viewModelContext.getDomainModel()).thenReturn(domainModel); + + final DummyRenderer dummyRenderer1 = createDummyRendererNoValidation(control1); + when(emfFormsRendererFactory.getRendererInstance(control1, viewModelContext)).thenReturn(dummyRenderer1); + + final CompoundControlSWTRenderer renderer = spy(createRenderer()); + + /* act */ + final Control label = renderer.createValidationIcon(shell); + + /* assert */ + verify(renderer, times(1)).createDummyValidationIcon(shell); + assertTrue(Label.class.isInstance(label)); + } + + @Test + public void testCreateValidationIconFirstCellRenderer2Columns() + throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, EMFFormsNoRendererException { + /* setup */ + final VControl control1 = mock(VControl.class); + final VFeaturePathDomainModelReference dmr1 = mock(VFeaturePathDomainModelReference.class); + when(control1.getDomainModelReference()).thenReturn(dmr1); + + final VControl control2 = mock(VControl.class); + final VFeaturePathDomainModelReference dmr2 = mock(VFeaturePathDomainModelReference.class); + when(control2.getDomainModelReference()).thenReturn(dmr2); + + when(compoundControl.getControls()).thenReturn(ECollections.asEList(control1, control2)); + + final EObject domainModel = mock(EObject.class); + when(viewModelContext.getDomainModel()).thenReturn(domainModel); + + final DummyRenderer dummyRenderer1 = spy(createDummyRenderer(control1)); + when(emfFormsRendererFactory.getRendererInstance(control1, viewModelContext)).thenReturn(dummyRenderer1); + + final CompoundControlSWTRenderer renderer = spy(createRenderer()); + + /* act */ + final Control label = renderer.createValidationIcon(shell); + + /* assert */ + verify(renderer, times(0)).createDummyValidationIcon(shell); + verify(dummyRenderer1, times(1)).createLabel(C_VALIDATION, shell); + assertTrue(Label.class.isInstance(label)); } @Test @@ -559,9 +1017,21 @@ public class CompoundControlSWTRenderer_ITest { @Test public void testRenderControlColumn1() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption { + when(compoundControl.getControls()).thenReturn(ECollections.<VControl> emptyEList()); final SWTGridCell swtGridCell = mock(SWTGridCell.class); when(swtGridCell.getColumn()).thenReturn(1); final CompoundControlSWTRenderer renderer = spy(createRenderer()); + doReturn(new Label(shell, SWT.NONE)).when(renderer).createLabel(shell); + renderer.renderControl(swtGridCell, shell); + verify(renderer, times(1)).createValidationIcon(shell); + } + + @Test + public void testRenderControlColumn2() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption { + when(compoundControl.getControls()).thenReturn(ECollections.<VControl> emptyEList()); + final SWTGridCell swtGridCell = mock(SWTGridCell.class); + when(swtGridCell.getColumn()).thenReturn(2); + final CompoundControlSWTRenderer renderer = spy(createRenderer()); doReturn(new Label(shell, SWT.NONE)).when(renderer).createControls(shell); renderer.renderControl(swtGridCell, shell); verify(renderer, times(1)).createControls(shell); @@ -569,10 +1039,36 @@ public class CompoundControlSWTRenderer_ITest { @Test(expected = IllegalArgumentException.class) public void testRenderControlColumnOther() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption { + when(compoundControl.getControls()).thenReturn(ECollections.<VControl> emptyEList()); final SWTGridCell swtGridCell = mock(SWTGridCell.class); - when(swtGridCell.getColumn()).thenReturn(2); + when(swtGridCell.getColumn()).thenReturn(3); + final CompoundControlSWTRenderer renderer = spy(createRenderer()); + renderer.renderControl(swtGridCell, shell); + } + + @Test + public void testRenderControlColumn0ControlLabelAlignmentNone() + throws NoRendererFoundException, NoPropertyDescriptorFoundExeption { + when(compoundControl.getLabelAlignment()).thenReturn(LabelAlignment.NONE); + final SWTGridCell swtGridCell = mock(SWTGridCell.class); + when(swtGridCell.getColumn()).thenReturn(0); final CompoundControlSWTRenderer renderer = spy(createRenderer()); + doReturn(new Label(shell, SWT.NONE)).when(renderer).createValidationIcon(shell); renderer.renderControl(swtGridCell, shell); + verify(renderer, times(1)).createValidationIcon(shell); + } + + @Test + public void testRenderControlColumn1ControlLabelAlignmentNone() + throws NoRendererFoundException, NoPropertyDescriptorFoundExeption { + when(compoundControl.getLabelAlignment()).thenReturn(LabelAlignment.NONE); + when(compoundControl.getControls()).thenReturn(ECollections.<VControl> emptyEList()); + final SWTGridCell swtGridCell = mock(SWTGridCell.class); + when(swtGridCell.getColumn()).thenReturn(1); + final CompoundControlSWTRenderer renderer = spy(createRenderer()); + doReturn(new Label(shell, SWT.NONE)).when(renderer).createControls(shell); + renderer.renderControl(swtGridCell, shell); + verify(renderer, times(1)).createControls(shell); } @Test @@ -619,7 +1115,7 @@ public class CompoundControlSWTRenderer_ITest { /* act */ renderer.init(); - final Control controls = renderer.render(new SWTGridCell(0, 1, renderer), shell); + final Control controls = renderer.render(new SWTGridCell(0, 2, renderer), shell); renderer.finalizeRendering(shell); /* assert */ @@ -641,23 +1137,33 @@ public class CompoundControlSWTRenderer_ITest { } private DummyRenderer createDummyRenderer(final VControl control) { - final DummyRenderer dummyRenderer = new DummyRenderer(control, viewModelContext, reportService); + final DummyRenderer dummyRenderer = new DummyRenderer(control, viewModelContext, reportService, true); dummyRenderer.init(); return dummyRenderer; } - private static final class DummyRenderer extends AbstractSWTRenderer<VElement> { + private DummyRenderer createDummyRendererNoValidation(final VControl control) { + final DummyRenderer dummyRenderer = new DummyRenderer(control, viewModelContext, reportService, false); + dummyRenderer.init(); + return dummyRenderer; + } + + public static class DummyRenderer extends AbstractSWTRenderer<VElement> { private SWTGridDescription rendererGridDescription; + private final boolean showValidation; - DummyRenderer(VControl vElement, ViewModelContext viewContext, ReportService reportService) { + DummyRenderer(VControl vElement, ViewModelContext viewContext, ReportService reportService, + boolean showValidation) { super(vElement, viewContext, reportService); + this.showValidation = showValidation; } @Override public SWTGridDescription getGridDescription(SWTGridDescription gridDescription) { if (rendererGridDescription == null) { - rendererGridDescription = GridDescriptionFactory.INSTANCE.createSimpleGrid(1, 2, this); + rendererGridDescription = GridDescriptionFactory.INSTANCE.createSimpleGrid(1, showValidation ? 2 : 1, + this); for (int i = 0; i < rendererGridDescription.getGrid().size() - 1; i++) { final SWTGridCell swtGridCell = rendererGridDescription.getGrid().get(i); swtGridCell.setHorizontalGrab(false); @@ -669,7 +1175,11 @@ public class CompoundControlSWTRenderer_ITest { @Override protected Control renderControl(SWTGridCell gridCell, Composite parent) throws NoRendererFoundException, NoPropertyDescriptorFoundExeption { - switch (gridCell.getColumn()) { + int column = gridCell.getColumn(); + if (!showValidation) { + column++; + } + switch (column) { case 0: return createLabel(C_VALIDATION, parent); case 1: @@ -679,7 +1189,7 @@ public class CompoundControlSWTRenderer_ITest { } } - private Control createLabel(String string, Composite parent) { + protected Control createLabel(String string, Composite parent) { final Label label = new Label(parent, SWT.NONE); label.setText(string); return label; |