Skip to content

Package: TextControlSWTRenderer$ModelToTargetUpdateStrategy

TextControlSWTRenderer$ModelToTargetUpdateStrategy

nameinstructionbranchcomplexitylinemethod
TextControlSWTRenderer.ModelToTargetUpdateStrategy(TextControlSWTRenderer, boolean)
M: 0 C: 10
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
convert(Object)
M: 11 C: 38
78%
M: 1 C: 5
83%
M: 1 C: 3
75%
M: 2 C: 10
83%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2014 EclipseSource Muenchen GmbH and others.
3: *
4: * All rights reserved. This program and the accompanying materials
5: * are made available under the terms of the Eclipse Public License 2.0
6: * which accompanies this distribution, and is available at
7: * https://www.eclipse.org/legal/epl-2.0/
8: *
9: * SPDX-License-Identifier: EPL-2.0
10: *
11: * Contributors:
12: * Eugen - initial API and implementation
13: ******************************************************************************/
14: package org.eclipse.emf.ecp.view.spi.core.swt.renderer;
15:
16: import java.util.Set;
17:
18: import javax.inject.Inject;
19:
20: import org.eclipse.core.databinding.Binding;
21: import org.eclipse.core.databinding.DataBindingContext;
22: import org.eclipse.core.databinding.UpdateValueStrategy;
23: import org.eclipse.core.databinding.observable.IObserving;
24: import org.eclipse.core.databinding.observable.value.IObservableValue;
25: import org.eclipse.core.databinding.property.value.IValueProperty;
26: import org.eclipse.emf.common.util.Diagnostic;
27: import org.eclipse.emf.databinding.EMFUpdateValueStrategy;
28: import org.eclipse.emf.ecore.EAttribute;
29: import org.eclipse.emf.ecore.EDataType;
30: import org.eclipse.emf.ecore.EStructuralFeature;
31: import org.eclipse.emf.ecore.InternalEObject;
32: import org.eclipse.emf.ecore.util.EcoreUtil;
33: import org.eclipse.emf.ecp.edit.internal.swt.util.PreSetValidationListeners;
34: import org.eclipse.emf.ecp.view.internal.core.swt.MessageKeys;
35: import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
36: import org.eclipse.emf.ecp.view.spi.core.swt.SimpleControlSWTControlSWTRenderer;
37: import org.eclipse.emf.ecp.view.spi.model.LabelAlignment;
38: import org.eclipse.emf.ecp.view.spi.model.VControl;
39: import org.eclipse.emf.ecp.view.spi.model.VElement;
40: import org.eclipse.emf.ecp.view.spi.model.VView;
41: import org.eclipse.emf.ecp.view.spi.model.VViewModelProperties;
42: import org.eclipse.emf.ecp.view.spi.provider.ECPTooltipModifierHelper;
43: import org.eclipse.emf.ecp.view.spi.swt.reporting.RenderingFailedReport;
44: import org.eclipse.emf.ecp.view.template.model.VTStyleProperty;
45: import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider;
46: import org.eclipse.emf.ecp.view.template.style.alignment.model.AlignmentType;
47: import org.eclipse.emf.ecp.view.template.style.alignment.model.VTAlignmentStyleProperty;
48: import org.eclipse.emf.ecp.view.template.style.textControlEnablement.model.VTTextControlEnablementStyleProperty;
49: import org.eclipse.emf.ecp.view.template.style.unsettable.model.ButtonPlacementType;
50: import org.eclipse.emf.edit.command.SetCommand;
51: import org.eclipse.emfforms.spi.common.report.ReportService;
52: import org.eclipse.emfforms.spi.common.validation.PreSetValidationService;
53: import org.eclipse.emfforms.spi.common.validation.PreSetValidationServiceRunnable;
54: import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException;
55: import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedReport;
56: import org.eclipse.emfforms.spi.core.services.databinding.EMFFormsDatabinding;
57: import org.eclipse.emfforms.spi.core.services.editsupport.EMFFormsEditSupport;
58: import org.eclipse.emfforms.spi.core.services.label.EMFFormsLabelProvider;
59: import org.eclipse.emfforms.spi.core.services.label.NoLabelFoundException;
60: import org.eclipse.emfforms.spi.localization.LocalizationServiceHelper;
61: import org.eclipse.emfforms.spi.swt.core.SWTDataElementIdHelper;
62: import org.eclipse.emfforms.spi.swt.core.layout.SWTGridCell;
63: import org.eclipse.emfforms.swt.core.EMFFormsSWTConstants;
64: import org.eclipse.jface.databinding.swt.typed.WidgetProperties;
65: import org.eclipse.jface.layout.GridDataFactory;
66: import org.eclipse.jface.layout.GridLayoutFactory;
67: import org.eclipse.swt.SWT;
68: import org.eclipse.swt.graphics.Color;
69: import org.eclipse.swt.widgets.Composite;
70: import org.eclipse.swt.widgets.Control;
71: import org.eclipse.swt.widgets.Text;
72:
73: /**
74: * Renders texts.
75: *
76: * @author Eugen Neufeld
77: * @since 1.5
78: *
79: */
80: public class TextControlSWTRenderer extends SimpleControlSWTControlSWTRenderer {
81:
82:         private final EMFFormsEditSupport emfFormsEditSupport;
83:
84:         /**
85:          * Default constructor.
86:          *
87:          * @param vElement the view model element to be rendered
88:          * @param viewContext the view context
89:          * @param reportService The {@link ReportService}
90:          * @param emfFormsDatabinding The {@link EMFFormsDatabinding}
91:          * @param emfFormsLabelProvider The {@link EMFFormsLabelProvider}
92:          * @param vtViewTemplateProvider The {@link VTViewTemplateProvider}
93:          * @param emfFormsEditSupport The {@link EMFFormsEditSupport}
94:          * @since 1.6
95:          */
96:         @Inject
97:         public TextControlSWTRenderer(VControl vElement, ViewModelContext viewContext,
98:                 ReportService reportService,
99:                 EMFFormsDatabinding emfFormsDatabinding, EMFFormsLabelProvider emfFormsLabelProvider,
100:                 VTViewTemplateProvider vtViewTemplateProvider, EMFFormsEditSupport emfFormsEditSupport) {
101:                 super(vElement, viewContext, reportService, emfFormsDatabinding, emfFormsLabelProvider, vtViewTemplateProvider);
102:                 this.emfFormsEditSupport = emfFormsEditSupport;
103:         }
104:
105:         @Override
106:         protected Binding[] createBindings(Control control) throws DatabindingFailedException {
107:                 final EStructuralFeature structuralFeature = (EStructuralFeature) getModelValue().getValueType();
108:                 final UpdateValueStrategy targetToModelUpdateStrategy = withPreSetValidation(
109:                         new TargetToModelUpdateStrategy(structuralFeature.isUnsettable()));
110:                 final ModelToTargetUpdateStrategy modelToTargetUpdateStrategy = new ModelToTargetUpdateStrategy(false);
111:                 final Binding binding = bindValue(control, getModelValue(), getDataBindingContext(),
112:                         targetToModelUpdateStrategy,
113:                         modelToTargetUpdateStrategy);
114:                 final Binding tooltipBinding = createTooltipBinding(control, getModelValue(), getDataBindingContext(),
115:                         targetToModelUpdateStrategy,
116:                         new ModelToTargetUpdateStrategy(true));
117:                 return new Binding[] { binding, tooltipBinding };
118:         }
119:
120:         @Override
121:         protected Control createSWTControl(Composite parent) {
122:                 final Composite composite = new Composite(parent, SWT.NONE);
123:                 GridLayoutFactory.fillDefaults().numColumns(1).equalWidth(true).applyTo(composite);
124:                 final Text text = new Text(composite, getTextWidgetStyle());
125:                 text.setData(CUSTOM_VARIANT, getTextVariantID());
126:                 SWTDataElementIdHelper.setElementIdDataForVControl(text, getVElement(), getViewModelContext());
127:                 text.setMessage(getTextMessage());
128:
129:                 try {
130:                         PreSetValidationListeners.create(getViewModelContext()).verify(text, getFeature(), getVElement());
131:                         PreSetValidationListeners.create(getViewModelContext()).focus(text, getFeature(),
132:                                 new PreSetValidationServiceRunnable() {
133:                                         @Override
134:                                         public void run(PreSetValidationService service) {
135:                                                 try {
136:                                                         final EDataType attributeType = ((EAttribute) getFeature()).getEAttributeType();
137:                                                         final String textFieldText = getTextFromTextField(text, attributeType);
138:                                                         final Object convertedValue = convert(text, attributeType, textFieldText);
139:                                                         final Diagnostic textDiag = service.validate(getFeature(), convertedValue);
140:                                                         final Diagnostic boundDiag = service.validate(getFeature(), getModelValue().getValue());
141:                                                         final boolean isEnteredValueValid = textDiag.getSeverity() == Diagnostic.OK;
142:                                                         final boolean isBoundValueValid = boundDiag.getSeverity() == Diagnostic.OK;
143:
144:                                                         if (getModelValue().getValue() != null && !isEnteredValueValid && isBoundValueValid) {
145:                                                                 // revert
146:                                                                 getVElement().setDiagnostic(null);
147:                                                                 getDataBindingContext().updateTargets();
148:                                                         }
149:                                                 } catch (final DatabindingFailedException e) {
150:                                                         // can we can do something reasonable here?
151:                                                 } catch (final IllegalArgumentException ex) {
152:                                                         // TODO: can the previously stored value be invalid?
153:                                                         // restore previous value and clear diagnostics
154:                                                         getVElement().setDiagnostic(null);
155:                                                         getDataBindingContext().updateTargets();
156:                                                         return;
157:                                                 }
158:                                         }
159:                                 },
160:                                 new Runnable() {
161:                                         @Override
162:                                         public void run() {
163:                                                 text.selectAll();
164:                                         }
165:                                 });
166:                 } catch (final DatabindingFailedException ex) {
167:                         // ignore
168:                 }
169:
170:                 final GridDataFactory gdf = GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
171:                         .grab(true, true).span(1, 1);
172:                 final EMFFormsEditSupport editSupport = getEMFFormsEditSupport();
173:                 if (editSupport.isMultiLine(getVElement().getDomainModelReference(), getViewModelContext().getDomainModel())) {
174:                         gdf.hint(50, 200);// set x hint to enable wrapping
175:                 }
176:                 gdf.applyTo(text);
177:                 return composite;
178:         }
179:
180:         /**
181:          * Convert the given value from target to model.
182:          *
183:          * @param text the Text control
184:          * @param attributeType the model data type
185:          * @param value the target value to convert
186:          * @return the converted value
187:          * @throws DatabindingFailedException in case the databinding failed
188:          * @since 1.13
189:          */
190:         protected Object convert(Text text, EDataType attributeType, String value) throws DatabindingFailedException {
191:                 return EcoreUtil.createFromString(attributeType, value);
192:         }
193:
194:         /**
195:          * Returns the text which should be set as the message text on the Text field.
196:          *
197:          * @return the string to show as the message
198:          * @since 1.6
199:          */
200:         protected String getTextMessage() {
201:                 try {
202:                         return (String) getEMFFormsLabelProvider()
203:                                 .getDisplayName(getVElement().getDomainModelReference(), getViewModelContext().getDomainModel())
204:                                 .getValue();
205:                 } catch (final NoLabelFoundException ex) {
206:                         // FIXME Expectations?
207:                         getReportService().report(new RenderingFailedReport(ex));
208:                 }
209:                 return ""; //$NON-NLS-1$
210:         }
211:
212:         /**
213:          * Creates a focus out binding for this control.
214:          *
215:          * @param text the {@link Text} to bind
216:          * @param modelValue the {@link IObservableValue} to bind
217:          * @param dataBindingContext the {@link DataBindingContext} to use
218:          * @param targetToModel the {@link UpdateValueStrategy} from target to Model
219:          * @param modelToTarget the {@link UpdateValueStrategy} from model to target
220:          * @return the created {@link Binding}
221:          */
222:         protected Binding bindValue(Control text, IObservableValue modelValue, DataBindingContext dataBindingContext,
223:                 UpdateValueStrategy targetToModel, UpdateValueStrategy modelToTarget) {
224:                 final Control controlToObserve = Composite.class.cast(text).getChildren()[0];
225:                 final boolean useOnModifyDatabinding = useOnModifyDatabinding();
226:                 final IObservableValue value;
227:                 if (useOnModifyDatabinding) {
228:                         value = WidgetProperties.text(SWT.Modify).observeDelayed(250, controlToObserve);
229:                 } else {
230:                         value = WidgetProperties.text(SWT.FocusOut).observe(controlToObserve);
231:                 }
232:                 final Binding binding = dataBindingContext.bindValue(value, modelValue, targetToModel, modelToTarget);
233:                 return binding;
234:         }
235:
236:         /**
237:          * Whether {@link SWT#Modify} or {@link SWT#FocusOut} shall be used as the target databinding trigger.
238:          *
239:          * @return <code>true</code> if Modify should be used, <code>false</code> otherwise
240:          * @since 1.9
241:          */
242:         protected boolean useOnModifyDatabinding() {
243:                 final VElement viewCandidate = getViewModelContext().getViewModel();
244:                 if (!VView.class.isInstance(viewCandidate)) {
245:                         return false;
246:                 }
247:                 final VViewModelProperties properties = VView.class.cast(viewCandidate).getLoadingProperties();
248:                 if (properties == null) {
249:                         return false;
250:                 }
251:                 return EMFFormsSWTConstants.USE_ON_MODIFY_DATABINDING_VALUE
252:                         .equalsIgnoreCase((String) properties.get(EMFFormsSWTConstants.USE_ON_MODIFY_DATABINDING_KEY));
253:         }
254:
255:         /**
256:          * Creates a tooltip binding for this control.
257:          *
258:          * @param text the {@link Text} to bind
259:          * @param modelValue the {@link IObservableValue} to bind
260:          * @param dataBindingContext the {@link DataBindingContext} to use
261:          * @param targetToModel the {@link UpdateValueStrategy} from target to Model
262:          * @param modelToTarget the {@link UpdateValueStrategy} from model to target
263:          * @return the created {@link Binding}
264:          */
265:         protected Binding createTooltipBinding(Control text, IObservableValue modelValue,
266:                 DataBindingContext dataBindingContext, UpdateValueStrategy targetToModel, UpdateValueStrategy modelToTarget) {
267:                 final IObservableValue toolTip = WidgetProperties.tooltipText().observe(text);
268:                 return dataBindingContext.bindValue(toolTip, modelValue, targetToModel, modelToTarget);
269:         }
270:
271:         /**
272:          * The style to apply to the text widget. This can be changed by the concrete classes.
273:          *
274:          * @return the style to apply
275:          */
276:         protected int getTextWidgetStyle() {
277:                 int textStyle = SWT.SINGLE | SWT.BORDER;
278:                 final EMFFormsEditSupport editSupport = getEMFFormsEditSupport();
279:                 if (editSupport.isMultiLine(getVElement().getDomainModelReference(), getViewModelContext().getDomainModel())) {
280:                         textStyle = SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER;
281:                 }
282:                 textStyle |= getAlignment();
283:                 return textStyle;
284:         }
285:
286:         /**
287:          *
288:          * @return the {@link EMFFormsEditSupport}
289:          * @since 1.10
290:          */
291:         protected EMFFormsEditSupport getEMFFormsEditSupport() {
292:                 return emfFormsEditSupport;
293:         }
294:
295:         private int getAlignment() {
296:                 if (getVTViewTemplateProvider() == null) {
297:                         return getDefaultAlignment();
298:                 }
299:                 final Set<VTStyleProperty> styleProperties = getVTViewTemplateProvider()
300:                         .getStyleProperties(getVElement(), getViewModelContext());
301:                 for (final VTStyleProperty styleProperty : styleProperties) {
302:                         if (VTAlignmentStyleProperty.class.isInstance(styleProperty)) {
303:                                 if (VTAlignmentStyleProperty.class.cast(styleProperty).getType() == AlignmentType.LEFT) {
304:                                         return SWT.LEFT;
305:                                 } else if (VTAlignmentStyleProperty.class.cast(styleProperty).getType() == AlignmentType.RIGHT) {
306:                                         return SWT.RIGHT;
307:                                 }
308:                         }
309:                 }
310:                 return getDefaultAlignment();
311:         }
312:
313:         /**
314:          * Return the default alignment value for this renderer.
315:          *
316:          * @return the alignment to use if no style was defined
317:          */
318:         protected int getDefaultAlignment() {
319:                 return SWT.LEFT;
320:         }
321:
322:         /**
323:          * The VariantId to use e.g. for RAP
324:          *
325:          * @return the String identifying this control
326:          */
327:         protected String getTextVariantID() {
328:                 return "org_eclipse_emf_ecp_control_string"; //$NON-NLS-1$
329:         }
330:
331:         @Override
332:         protected void setControlEnabled(SWTGridCell gridCell, Control control, boolean enabled) {
333:                 if (isDisableRenderedAsEditable()
334:                         && (getVElement().getLabelAlignment() == LabelAlignment.NONE && gridCell.getColumn() == 1
335:                                 || hasLeftLabelAlignment() && gridCell.getColumn() == 2)) {
336:                         Control controlToUnset = control;
337:                         if (isControlUnsettable()) {
338:                                 // if (!setting.isSet()) {
339:                                 // return;
340:                                 // }
341:                                 controlToUnset = Composite.class
342:                                         .cast(Composite.class.cast(getControlCompositeFromControl(control)).getChildren()[0])
343:                                         .getChildren()[0];
344:                         } else {
345:                                 controlToUnset = Composite.class.cast(control).getChildren()[0];
346:                         }
347:                         Text.class.cast(controlToUnset).setEditable(enabled);
348:                 } else {
349:                         if (getVElement().getLabelAlignment() == LabelAlignment.NONE && gridCell.getColumn() == 1
350:                                 || hasLeftLabelAlignment() && gridCell.getColumn() == 2) {
351:                                 super.setControlEnabled(gridCell, getControlCompositeFromControl(control), enabled);
352:                         } else {
353:                                 super.setControlEnabled(gridCell, control, enabled);
354:                         }
355:                 }
356:         }
357:
358:         private boolean isControlUnsettable() {
359:                 IValueProperty valueProperty;
360:                 try {
361:                         valueProperty = getEMFFormsDatabinding()
362:                                 .getValueProperty(getVElement().getDomainModelReference(), getViewModelContext().getDomainModel());
363:                 } catch (final DatabindingFailedException ex) {
364:                         getReportService().report(new RenderingFailedReport(ex));
365:                         return false;
366:                 }
367:                 final EStructuralFeature feature = (EStructuralFeature) valueProperty.getValueType();
368:                 final boolean unsettable = feature.isUnsettable();
369:                 return unsettable;
370:         }
371:
372:         private boolean isDisableRenderedAsEditable() {
373:                 final VTViewTemplateProvider vtViewTemplateProvider = getVTViewTemplateProvider();
374:                 if (vtViewTemplateProvider == null) {
375:                         return false;
376:                 }
377:                 final Set<VTStyleProperty> styleProperties = vtViewTemplateProvider
378:                         .getStyleProperties(getVElement(), getViewModelContext());
379:                 for (final VTStyleProperty styleProperty : styleProperties) {
380:                         if (VTTextControlEnablementStyleProperty.class.isInstance(styleProperty)) {
381:                                 return VTTextControlEnablementStyleProperty.class.cast(styleProperty).isRenderDisableAsEditable();
382:                         }
383:                 }
384:                 return false;
385:         }
386:
387:         /**
388:          * Gets the text displayed in the textfield.
389:          *
390:          * @param text the {@link Text}
391:          * @param attributeType the {@link EDataType}
392:          * @return the string displayed in the {@link Text}
393:          * @since 1.13
394:          */
395:         protected String getTextFromTextField(final Text text, EDataType attributeType) {
396:                 return text.getText();
397:         }
398:
399:         /**
400:          * An {@link EMFUpdateConvertValueStrategy} that encapsulates the converting
401:          * of the actual value. Use this class to provide a specific context
402:          * for the conversion of the value, but likewise enable it clients to modify
403:          * the conversion behavior.
404:          *
405:          * @author emueller
406:          *
407:          */
408:         class EMFUpdateConvertValueStrategy extends EMFUpdateValueStrategy {
409:
410:                 /*
411:                  * (non-Javadoc)
412:                  * @see org.eclipse.core.databinding.UpdateValueStrategy#convert(java.lang.Object)
413:                  */
414:                 @Override
415:                 public Object convert(Object value) {
416:                         return convertValue(value);
417:                 }
418:
419:                 /**
420:                  * Convert a value.
421:                  *
422:                  * @param value the value to convert
423:                  * @return the converted value
424:                  */
425:                 protected Object convertValue(Object value) {
426:                         return super.convert(value);
427:                 }
428:         }
429:
430:         /**
431:          * The strategy to convert from model to target.
432:          *
433:          * @author Eugen Neufeld
434:          *
435:          */
436:         protected class ModelToTargetUpdateStrategy extends EMFUpdateConvertValueStrategy {
437:
438:                 private final boolean tooltip;
439:
440:                 /**
441:                  * Constructor.
442:                  *
443:                  * @param tooltip <code>true</code> if the to be converted value is a tooltip and should be modified by a
444:                  * {@link org.eclipse.emf.ecp.view.spi.provider.ECPStringModifier ECPStringModifier},
445:                  * <code>false</code> otherwise.
446:                  */
447:                 public ModelToTargetUpdateStrategy(boolean tooltip) {
448:                         this.tooltip = tooltip;
449:
450:                 }
451:
452:                 @Override
453:                 public Object convert(Object value) {
454:                         final Object converted = convertValue(value);
455:•                        if (tooltip && String.class.isInstance(converted)) {
456:                                 IObservableValue observableValue;
457:                                 try {
458:                                         observableValue = getModelValue();
459:                                 } catch (final DatabindingFailedException ex) {
460:                                         getReportService().report(new DatabindingFailedReport(ex));
461:                                         return converted;
462:                                 }
463:                                 final InternalEObject internalEObject = (InternalEObject) ((IObserving) observableValue).getObserved();
464:•                                if (internalEObject != null) {
465:                                         final EStructuralFeature structuralFeature = (EStructuralFeature) observableValue.getValueType();
466:                                         return ECPTooltipModifierHelper.modifyString(String.class.cast(converted),
467:                                                 internalEObject.eSetting(structuralFeature));
468:                                 }
469:                         }
470:                         return converted;
471:                 }
472:
473:         }
474:
475:         /**
476:          * The strategy to convert from target to model.
477:          *
478:          * @author Eugen
479:          *
480:          */
481:         protected class TargetToModelUpdateStrategy extends EMFUpdateConvertValueStrategy {
482:
483:                 private final boolean unsetable;
484:
485:                 /**
486:                  * Constructor for indicating whether a value is unsettable.
487:                  *
488:                  * @param unsettable true if value is unsettable, false otherwise
489:                  */
490:                 public TargetToModelUpdateStrategy(boolean unsettable) {
491:                         unsetable = unsettable;
492:
493:                 }
494:
495:                 /**
496:                  * {@inheritDoc}
497:                  */
498:                 @Override
499:                 public Object convert(Object value) {
500:                         try {
501:                                 if ("".equals(value)) { //$NON-NLS-1$
502:                                         value = null;
503:                                 }
504:                                 if (value == null && unsetable) {
505:                                         return SetCommand.UNSET_VALUE;
506:                                 }
507:
508:                                 return convertValue(value);
509:
510:                         } catch (final IllegalArgumentException e) {
511:                                 throw e;
512:                         }
513:                 }
514:         }
515:
516:         /**
517:          * {@inheritDoc}
518:          *
519:          * @see org.eclipse.emf.ecp.view.spi.core.swt.SimpleControlSWTRenderer#getUnsetText()
520:          */
521:         @Override
522:         protected String getUnsetText() {
523:                 return LocalizationServiceHelper
524:                         .getString(TextControlSWTRenderer.class, MessageKeys.StringControl_NoTextSetClickToSetText);
525:         }
526:
527:         @Override
528:         protected void setValidationColor(Control control, Color validationColor) {
529:                 super.setValidationColor(getControlCompositeFromControl(control), validationColor);
530:         }
531:
532:         @Override
533:         protected void setValidationForegroundColor(Control control, Color validationColor) {
534:                 super.setValidationForegroundColor(getControlCompositeFromControl(control), validationColor);
535:         }
536:
537:         /**
538:          * Returns whether the unset button is placed left of the control composite containing the text field.
539:          *
540:          * @return <code>true</code> if the control is unsettable and the unset button is left of the text field,
541:          * <code>false</code> otherwise
542:          * @since 1.14
543:          */
544:         protected boolean isUnsetButtonLeftOfControlComposite() {
545:                 return isControlUnsettable()
546:                         && getUnsettableStyleProperty().getButtonPlacement() == ButtonPlacementType.LEFT_OF_LABEL;
547:         }
548:
549:         /**
550:          * Returns the control composite that contains the text field from the parent composite created by the
551:          * {@link org.eclipse.emf.ecp.view.spi.core.swt.SimpleControlSWTRenderer SimpleControlSWTRenderer}.
552:          *
553:          * @param control The edit control created by the
554:          * {@link org.eclipse.emf.ecp.view.spi.core.swt.SimpleControlSWTRenderer SimpleControlSWTRenderer}
555:          * @return the control composite containing the text field
556:          * @since 1.14
557:          */
558:         protected Control getControlCompositeFromControl(Control control) {
559:                 if (isUnsetButtonLeftOfControlComposite()) {
560:                         return Composite.class.cast(control).getChildren()[1];
561:                 }
562:                 return Composite.class.cast(control).getChildren()[0];
563:         }
564: }