Skip to content

Package: AbstractControlSWTRenderer

AbstractControlSWTRenderer

nameinstructionbranchcomplexitylinemethod
AbstractControlSWTRenderer(VControl, ViewModelContext, ReportService, EMFFormsDatabinding, EMFFormsLabelProvider, VTViewTemplateProvider)
M: 0 C: 13
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
AbstractControlSWTRenderer(VControl, ViewModelContext, ReportService, EMFFormsDatabinding, EMFFormsLabelProvider, VTViewTemplateProvider, SWTValidationHelper)
M: 0 C: 12
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
AbstractControlSWTRenderer(VControl, ViewModelContext, ReportService, EMFFormsDatabinding, EMFFormsLabelProvider, VTViewTemplateProvider, SWTValidationUiService)
M: 0 C: 47
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 13
100%
M: 0 C: 1
100%
applyEnable()
M: 1 C: 75
99%
M: 2 C: 8
80%
M: 2 C: 4
67%
M: 0 C: 11
100%
M: 0 C: 1
100%
applyReadOnly()
M: 0 C: 30
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
applyUnchangeableFeature()
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
canHandleControlProcessor()
M: 0 C: 2
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
createLabel(Composite)
M: 26 C: 87
77%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 6 C: 23
79%
M: 0 C: 1
100%
createValidationIcon(Composite)
M: 0 C: 19
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
defaultHandleControlProcessor(Control)
M: 0 C: 20
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
defaultHandleControlProcessorForCell(Control, SWTGridCell)
M: 0 C: 8
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
dispose()
M: 0 C: 36
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 12
100%
M: 0 C: 1
100%
getDataBindingContext()
M: 0 C: 11
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
getEMFFormsDatabinding()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getEMFFormsLabelProvider()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getEditingDomain(EObject)
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getLabelStyleBits()
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
getMandatoryStyle()
M: 0 C: 9
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
getModelValue()
M: 15 C: 26
63%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 3 C: 7
70%
M: 0 C: 1
100%
getVTViewTemplateProvider()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getValidationBackgroundColor()
M: 2 C: 11
85%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 1 C: 2
67%
M: 0 C: 1
100%
getValidationBackgroundColor(int)
M: 2 C: 32
94%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 1 C: 6
86%
M: 0 C: 1
100%
getValidationForegroundColor()
M: 2 C: 11
85%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 1 C: 2
67%
M: 0 C: 1
100%
getValidationForegroundColor(int)
M: 2 C: 32
94%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 1 C: 6
86%
M: 0 C: 1
100%
getValidationIcon()
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getValidationIcon(int)
M: 0 C: 29
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
hasLeftLabelAlignment()
M: 0 C: 16
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
isUnchangeableFeature()
M: 0 C: 56
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 13
100%
M: 0 C: 1
100%
notifyChange()
M: 9 C: 13
59%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 1 C: 6
86%
M: 0 C: 1
100%
postInit()
M: 0 C: 28
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 9
100%
M: 0 C: 1
100%
render(SWTGridCell, Composite)
M: 2 C: 16
89%
M: 2 C: 2
50%
M: 2 C: 1
33%
M: 1 C: 5
83%
M: 0 C: 1
100%
rootDomainModelChanged()
M: 0 C: 1
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2019 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;
15:
16: import java.util.LinkedHashMap;
17: import java.util.Map;
18:
19: import org.eclipse.core.databinding.DataBindingContext;
20: import org.eclipse.core.databinding.UpdateValueStrategy;
21: import org.eclipse.core.databinding.observable.IObserving;
22: import org.eclipse.core.databinding.observable.value.IObservableValue;
23: import org.eclipse.core.databinding.property.value.IValueProperty;
24: import org.eclipse.core.runtime.IStatus;
25: import org.eclipse.emf.databinding.EMFDataBindingContext;
26: import org.eclipse.emf.ecore.EObject;
27: import org.eclipse.emf.ecore.EStructuralFeature;
28: import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
29: import org.eclipse.emf.ecp.view.spi.model.LabelAlignment;
30: import org.eclipse.emf.ecp.view.spi.model.ModelChangeListener;
31: import org.eclipse.emf.ecp.view.spi.model.ModelChangeNotification;
32: import org.eclipse.emf.ecp.view.spi.model.VControl;
33: import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference;
34: import org.eclipse.emf.ecp.view.spi.model.VElement;
35: import org.eclipse.emf.ecp.view.spi.renderer.NoPropertyDescriptorFoundExeption;
36: import org.eclipse.emf.ecp.view.spi.renderer.NoRendererFoundException;
37: import org.eclipse.emf.ecp.view.spi.swt.reporting.RenderingFailedReport;
38: import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider;
39: import org.eclipse.emf.ecp.view.template.style.mandatory.model.VTMandatoryStyleProperty;
40: import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
41: import org.eclipse.emf.edit.domain.EditingDomain;
42: import org.eclipse.emfforms.spi.common.report.AbstractReport;
43: import org.eclipse.emfforms.spi.common.report.ReportService;
44: import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException;
45: import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedReport;
46: import org.eclipse.emfforms.spi.core.services.databinding.EMFFormsDatabinding;
47: import org.eclipse.emfforms.spi.core.services.label.EMFFormsLabelProvider;
48: import org.eclipse.emfforms.spi.core.services.label.NoLabelFoundException;
49: import org.eclipse.emfforms.spi.core.services.structuralchange.EMFFormsStructuralChangeTester;
50: import org.eclipse.emfforms.spi.core.services.view.RootDomainModelChangeListener;
51: import org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer;
52: import org.eclipse.emfforms.spi.swt.core.EMFFormsControlProcessorService;
53: import org.eclipse.emfforms.spi.swt.core.SWTDataElementIdHelper;
54: import org.eclipse.emfforms.spi.swt.core.layout.SWTGridCell;
55: import org.eclipse.emfforms.spi.swt.core.ui.SWTValidationHelper;
56: import org.eclipse.emfforms.spi.swt.core.ui.SWTValidationUiService;
57: import org.eclipse.jface.databinding.swt.typed.WidgetProperties;
58: import org.eclipse.swt.SWT;
59: import org.eclipse.swt.graphics.Color;
60: import org.eclipse.swt.graphics.Image;
61: import org.eclipse.swt.widgets.Composite;
62: import org.eclipse.swt.widgets.Control;
63: import org.eclipse.swt.widgets.Display;
64: import org.eclipse.swt.widgets.Label;
65:
66: /**
67: * Super class for all kinds of control renderer.
68: *
69: * @param <VCONTROL> the {@link VControl} of this renderer.
70: * @author Eugen Neufeld
71: *
72: */
73: public abstract class AbstractControlSWTRenderer<VCONTROL extends VControl> extends AbstractSWTRenderer<VCONTROL>
74:         implements RootDomainModelChangeListener {
75:
76:         private SWTValidationHelper swtValidationHelper = SWTValidationHelper.INSTANCE;
77:         private final EMFFormsDatabinding emfFormsDatabinding;
78:         private final EMFFormsLabelProvider emfFormsLabelProvider;
79:         private final VTViewTemplateProvider vtViewTemplateProvider;
80:         private boolean isDisposed;
81:         private IObservableValue modelValue;
82:
83:         private final Map<Integer, Color> severityBackgroundColorMap = new LinkedHashMap<Integer, Color>();
84:         private final Map<Integer, Color> severityForegroundColorMap = new LinkedHashMap<Integer, Color>();
85:         private final Map<Integer, Image> severityIconMap = new LinkedHashMap<Integer, Image>();
86:         private final SWTValidationUiService validationUiService;
87:
88:         /**
89:          * Default constructor.
90:          *
91:          * @param vElement the view model element to be rendered
92:          * @param viewContext the view context
93:          * @param emfFormsDatabinding The {@link EMFFormsDatabinding}
94:          * @param emfFormsLabelProvider The {@link EMFFormsLabelProvider}
95:          * @param reportService The {@link ReportService}
96:          * @param vtViewTemplateProvider The {@link VTViewTemplateProvider}
97:          * @since 1.6
98:          */
99:         public AbstractControlSWTRenderer(VCONTROL vElement, ViewModelContext viewContext, ReportService reportService,
100:                 EMFFormsDatabinding emfFormsDatabinding, EMFFormsLabelProvider emfFormsLabelProvider,
101:                 VTViewTemplateProvider vtViewTemplateProvider) {
102:                 this(vElement, viewContext, reportService, emfFormsDatabinding, emfFormsLabelProvider, vtViewTemplateProvider,
103:                         viewContext.getService(SWTValidationUiService.class));
104:         }
105:
106:         /**
107:          * Additional constructor allowing to specify a custom {@link SWTValidationHelper}.
108:          *
109:          * @param vElement the view model element to be rendered
110:          * @param viewContext the view context
111:          * @param emfFormsDatabinding The {@link EMFFormsDatabinding}
112:          * @param emfFormsLabelProvider The {@link EMFFormsLabelProvider}
113:          * @param reportService The {@link ReportService}
114:          * @param vtViewTemplateProvider The {@link VTViewTemplateProvider}
115:          * @param swtValidationHelper The {@link SWTValidationHelper}
116:          * @since 1.23
117:          */
118:         public AbstractControlSWTRenderer(VCONTROL vElement, ViewModelContext viewContext, ReportService reportService,
119:                 EMFFormsDatabinding emfFormsDatabinding, EMFFormsLabelProvider emfFormsLabelProvider,
120:                 VTViewTemplateProvider vtViewTemplateProvider, SWTValidationHelper swtValidationHelper) {
121:                 this(vElement, viewContext, reportService, emfFormsDatabinding, emfFormsLabelProvider, vtViewTemplateProvider);
122:                 this.swtValidationHelper = swtValidationHelper;
123:         }
124:
125:         /**
126:          * Default constructor.
127:          *
128:          * @param vElement the view model element to be rendered
129:          * @param viewContext the view context
130:          * @param emfFormsDatabinding The {@link EMFFormsDatabinding}
131:          * @param emfFormsLabelProvider The {@link EMFFormsLabelProvider}
132:          * @param reportService The {@link ReportService}
133:          * @param vtViewTemplateProvider The {@link VTViewTemplateProvider}
134:          * @param validationUiService The {@link SWTValidationUiService}
135:          * @since 1.23
136:          */
137:         public AbstractControlSWTRenderer(VCONTROL vElement, ViewModelContext viewContext, ReportService reportService,
138:                 EMFFormsDatabinding emfFormsDatabinding, EMFFormsLabelProvider emfFormsLabelProvider,
139:                 VTViewTemplateProvider vtViewTemplateProvider, SWTValidationUiService validationUiService) {
140:                 super(vElement, viewContext, reportService);
141:                 this.emfFormsDatabinding = emfFormsDatabinding;
142:                 this.emfFormsLabelProvider = emfFormsLabelProvider;
143:                 this.vtViewTemplateProvider = vtViewTemplateProvider;
144:                 this.validationUiService = validationUiService;
145:                 viewModelDBC = new EMFDataBindingContext();
146:                 viewContext.registerRootDomainModelChangeListener(this);
147:                 isDisposed = false;
148:         }
149:
150:         /**
151:          * The {@link EMFFormsDatabinding} to use.
152:          *
153:          * @return The EMFFormsDatabinding
154:          * @since 1.6
155:          */
156:         protected EMFFormsDatabinding getEMFFormsDatabinding() {
157:                 return emfFormsDatabinding;
158:         }
159:
160:         /**
161:          * The {@link EMFFormsLabelProvider} to use.
162:          *
163:          * @return The EMFFormsLabelProvider
164:          * @since 1.6
165:          */
166:         protected EMFFormsLabelProvider getEMFFormsLabelProvider() {
167:                 return emfFormsLabelProvider;
168:         }
169:
170:         /**
171:          * The {@link VTViewTemplateProvider} to use.
172:          *
173:          * @return The VTViewTemplateProvider
174:          * @since 1.6
175:          */
176:         protected VTViewTemplateProvider getVTViewTemplateProvider() {
177:                 return vtViewTemplateProvider;
178:         }
179:
180:         private DataBindingContext dataBindingContext;
181:         private ModelChangeListener modelChangeListener;
182:         private final EMFDataBindingContext viewModelDBC;
183:
184:         @Override
185:         protected void postInit() {
186:                 super.postInit();
187:                 modelChangeListener = new ModelChangeListener() {
188:
189:                         @Override
190:                         public void notifyChange(ModelChangeNotification notification) {
191:                                 if (isDisposed) {
192:                                         return;
193:                                 }
194:                                 // Execute applyEnable whenever the structure of the VControl's DMR has been changed.
195:                                 final EMFFormsStructuralChangeTester changeTester = getViewModelContext()
196:                                         .getService(EMFFormsStructuralChangeTester.class);
197:                                 if (changeTester.isStructureChanged(getVElement().getDomainModelReference(),
198:                                         getViewModelContext().getDomainModel(), notification)) {
199:
200:                                         Display.getDefault().asyncExec(() -> {
201:                                                 if (!isDisposed) {
202:                                                         applyEnable();
203:                                                 }
204:                                         });
205:                                 }
206:
207:                         }
208:                 };
209:
210:•                if (getVElement().getDomainModelReference() != null) {
211:                         getViewModelContext().registerDomainChangeListener(modelChangeListener);
212:                 }
213:                 applyEnable();
214:                 applyReadOnly();
215:•                if (isUnchangeableFeature()) {
216:                         applyUnchangeableFeature();
217:                 }
218:         }
219:
220:         /**
221:          * Checks if the value referenced by the DMR can be changed or not by the user.
222:          *
223:          * @return <code>true</code> if the value cannot be changed.
224:          */
225:         protected boolean isUnchangeableFeature() {
226:                 final VDomainModelReference ref = getVElement().getDomainModelReference();
227:•                if (ref == null) {
228:                         getReportService()
229:                                 .report(new AbstractReport(
230:                                         String.format("No DomainModelReference could be found for the VElement %1$s.", //$NON-NLS-1$
231:                                                 getVElement().getName()),
232:                                         IStatus.ERROR));
233:                 }
234:                 final EObject eObject = getViewModelContext().getDomainModel();
235:                 try {
236:                         @SuppressWarnings("rawtypes")
237:                         final IValueProperty valueProperty = getEMFFormsDatabinding().getValueProperty(ref, eObject);
238:•                        return !EStructuralFeature.class.cast(valueProperty.getValueType()).isChangeable();
239:                 } catch (final DatabindingFailedException ex) {
240:                         getReportService().report(new DatabindingFailedReport(ex));
241:                         return false;
242:                 }
243:         }
244:
245:         @Override
246:         public Control render(SWTGridCell cell, Composite parent)
247:                 throws NoRendererFoundException, NoPropertyDescriptorFoundExeption {
248:                 final Control control = super.render(cell, parent);
249:
250:•                if (control == null) {
251:                         return null;
252:                 }
253:
254:•                if (!canHandleControlProcessor()) {
255:                         defaultHandleControlProcessorForCell(control, cell);
256:                 }
257:
258:                 return control;
259:         }
260:
261:         /**
262:          * This method is applied if the control's feature is configured as unchangeable.
263:          * The renderer is usually disabled when feature is not changeable.
264:          *
265:          * @since 1.20
266:          */
267:         protected void applyUnchangeableFeature() {
268:                 getVElement().setReadonly(true);
269:         }
270:
271:         /**
272:          * <p>
273:          * Indicates if the given Control SWT renderer takes the responsibility to call a possibly existing
274:          * {@link EMFFormsControlProcessorService} itself.
275:          * </p>
276:          * <p>
277:          * The default implementation returns {@code false}.
278:          * </p>
279:          *
280:          * @return
281:          * {@code true} if the Control SWT renderer can handle the {@link EMFFormsControlProcessorService} itself,
282:          * {@code false} otherwise.
283:          * @since 1.8
284:          */
285:         protected boolean canHandleControlProcessor() {
286:                 return false;
287:         }
288:
289:         /**
290:          * This method is called by {link {@link #render(SWTGridCell, Composite)} for each
291:          * {@code control} and {@code cell} if {@link #canHandleControlProcessor()} returns {@code false}. The default
292:          * implementation forwards to {@link #defaultHandleControlProcessor(Control)} if the cell's column is {@code 2}.
293:          *
294:          * @param control
295:          * The {@link Control} which is to be processed by the {@link EMFFormsControlProcessorService}.
296:          * @param cell
297:          * The {@link SWTGridCell} for the given {@code control}.
298:          * @since 1.8
299:          */
300:         protected void defaultHandleControlProcessorForCell(Control control, SWTGridCell cell) {
301:•                if (cell.getColumn() == 2) {
302:                         defaultHandleControlProcessor(control);
303:                 }
304:         }
305:
306:         /**
307:          * Calls a possibly existing {@link EMFFormsControlProcessorService} for the given {@code control}.
308:          *
309:          * @param control
310:          * The {@link Control} which is to be processed by the {@link EMFFormsControlProcessorService}.
311:          * @since 1.8
312:          */
313:         protected void defaultHandleControlProcessor(Control control) {
314:•                if (getViewModelContext().hasService(EMFFormsControlProcessorService.class)) {
315:                         final EMFFormsControlProcessorService service = getViewModelContext()
316:                                 .getService(EMFFormsControlProcessorService.class);
317:                         service.process(control, getVElement(), getViewModelContext());
318:                 }
319:         }
320:
321:         @Override
322:         protected void dispose() {
323:                 isDisposed = true;
324:                 getViewModelContext().unregisterDomainChangeListener(modelChangeListener);
325:
326:                 getViewModelContext().unregisterRootDomainModelChangeListener(this);
327:
328:                 modelChangeListener = null;
329:
330:•                if (dataBindingContext != null) {
331:                         dataBindingContext.dispose();
332:                         dataBindingContext = null;
333:                 }
334:                 viewModelDBC.dispose();
335:•                if (modelValue != null) {
336:                         modelValue.dispose();
337:                 }
338:                 super.dispose();
339:         }
340:
341:         /**
342:          * Returns the validation icon matching the given severity.
343:          *
344:          * @param severity the severity of the {@link org.eclipse.emf.common.util.Diagnostic}
345:          * @return the icon to be displayed, or <code>null</code> when no icon is to be displayed
346:          * @deprecated use {@link #getValidationIcon()} for default behavior or use the
347:          * {@link SWTValidationUiService} if you need to get the color for a specific diagnostic.
348:          */
349:         @Deprecated
350:         protected final Image getValidationIcon(int severity) {
351:•                if (!severityIconMap.containsKey(severity)) {
352:                         final Image validationIcon = swtValidationHelper.getValidationIcon(severity, getVElement(),
353:                                 getViewModelContext());
354:                         severityIconMap.put(severity, validationIcon);
355:                 }
356:                 return severityIconMap.get(severity);
357:         }
358:
359:         /**
360:          * Returns the validation icon for the current validation result of this control's {@link VElement}.
361:          *
362:          * @return the icon to be displayed, or <code>null</code> when no icon is to be displayed
363:          * @since 1.23
364:          */
365:         protected final Image getValidationIcon() {
366:                 return validationUiService.getValidationIcon(getVElement(), getViewModelContext());
367:         }
368:
369:         /**
370:          * Returns the background color for a control with the given validation severity.
371:          *
372:          * @param severity severity the severity of the {@link org.eclipse.emf.common.util.Diagnostic}
373:          * @return the color to be used as a background color
374:          * @deprecated use {@link #getValidationBackgroundColor()} for default behavior or use the
375:          * {@link SWTValidationUiService} if you need to get the color for a specific diagnostic.
376:          */
377:         @Deprecated
378:         protected final Color getValidationBackgroundColor(int severity) {
379:•                if (isDisposed) {
380:                         return null;
381:                 }
382:
383:•                if (!severityBackgroundColorMap.containsKey(severity)) {
384:                         final Color validationBackgroundColor = swtValidationHelper
385:                                 .getValidationBackgroundColor(severity, getVElement(), getViewModelContext());
386:                         severityBackgroundColorMap.put(severity, validationBackgroundColor);
387:                 }
388:                 return severityBackgroundColorMap.get(severity);
389:         }
390:
391:         /**
392:          * Returns the background color for the current validation result of this control's {@link VElement}.
393:          *
394:          * @return the color to be used as a background color
395:          * @since 1.23
396:          */
397:         protected final Color getValidationBackgroundColor() {
398:•                if (isDisposed) {
399:                         return null;
400:                 }
401:                 return validationUiService.getValidationBackgroundColor(getVElement(), getViewModelContext());
402:         }
403:
404:         /**
405:          * Returns the foreground color for a control with the given validation severity.
406:          *
407:          * @param severity severity the severity of the {@link org.eclipse.emf.common.util.Diagnostic}
408:          * @return the color to be used as a foreground color
409:          * @since 1.10
410:          * @deprecated use {@link #getValidationForegroundColor()} for default behavior or use the
411:          * {@link SWTValidationUiService} if you need to get the color for a specific diagnostic.
412:          */
413:         @Deprecated
414:         protected final Color getValidationForegroundColor(int severity) {
415:•                if (isDisposed) {
416:                         return null;
417:                 }
418:
419:•                if (!severityForegroundColorMap.containsKey(severity)) {
420:                         final Color validationForegroundColor = swtValidationHelper
421:                                 .getValidationForegroundColor(severity, getVElement(), getViewModelContext());
422:                         severityForegroundColorMap.put(severity, validationForegroundColor);
423:                 }
424:                 return severityForegroundColorMap.get(severity);
425:
426:         }
427:
428:         /**
429:          * Returns the foreground color for the current validation result of this control's {@link VElement}.
430:          *
431:          * @return the color to be used as a foreground color
432:          * @since 1.23
433:          */
434:         protected final Color getValidationForegroundColor() {
435:•                if (isDisposed) {
436:                         return null;
437:                 }
438:                 return validationUiService.getValidationForegroundColor(getVElement(), getViewModelContext());
439:
440:         }
441:
442:         /**
443:          * Creates a new {@link DataBindingContext}.
444:          *
445:          * @return a new {@link DataBindingContext} each time this method is called
446:          */
447:         protected final DataBindingContext getDataBindingContext() {
448:•                if (dataBindingContext == null) {
449:                         dataBindingContext = new EMFDataBindingContext();
450:                 }
451:                 return dataBindingContext;
452:         }
453:
454:         /**
455:          * Returns an {@link IObservableValue} based on the control's domain model reference and domain model.
456:          *
457:          * @return the {@link IObservableValue}
458:          * @throws DatabindingFailedException if the databinding of the domain model object fails.
459:          * @since 1.6
460:          */
461:         protected final IObservableValue getModelValue() throws DatabindingFailedException {
462:•                if (modelValue == null) {
463:                         final VDomainModelReference ref = getVElement().getDomainModelReference();
464:•                        if (ref == null) {
465:                                 throw new DatabindingFailedException(String
466:                                         .format(
467:                                                 "No DomainModelReference could be found for the VElement %1$s.", getVElement().getName())); //$NON-NLS-1$
468:                         }
469:                         final EObject eObject = getViewModelContext().getDomainModel();
470:
471:                         final EMFFormsDatabinding databindingService = getEMFFormsDatabinding();
472:                         modelValue = databindingService.getObservableValue(ref, eObject);
473:                 }
474:                 return modelValue;
475:         }
476:
477:         /**
478:          * Returns the {@link EditingDomain} for the provided {@link EObject domain model}.
479:          *
480:          * @param domainModel The provided {@link EObject domain model}
481:          * @return The {@link EditingDomain} of this {@link EObject domain model}
482:          * @since 1.6
483:          */
484:         protected final EditingDomain getEditingDomain(EObject domainModel) {
485:                 return AdapterFactoryEditingDomain.getEditingDomainFor(domainModel);
486:         }
487:
488:         /**
489:          * Create the {@link Control} displaying the label of the current {@link VControl}.
490:          *
491:          * @param parent the {@link Composite} to render onto
492:          * @return the created {@link Control} or null
493:          */
494:         protected Control createLabel(final Composite parent) {
495:                 Label label = null;
496:•                labelRender: if (hasLeftLabelAlignment()) {
497:                         final VDomainModelReference domainModelReference = getVElement().getDomainModelReference();
498:                         final IValueProperty valueProperty;
499:                         try {
500:                                 valueProperty = getEMFFormsDatabinding().getValueProperty(domainModelReference,
501:                                         getViewModelContext().getDomainModel());
502:                         } catch (final DatabindingFailedException ex) {
503:                                 getReportService().report(new RenderingFailedReport(ex));
504:                                 break labelRender;
505:                         } catch (final IllegalArgumentException ex) {
506:                                 getReportService().report(new AbstractReport(ex));
507:                                 break labelRender;
508:                         }
509:
510:                         final EMFFormsLabelProvider labelProvider = getEMFFormsLabelProvider();
511:                         label = new Label(parent, getLabelStyleBits());
512:                         label.setData(CUSTOM_VARIANT, "org_eclipse_emf_ecp_control_label"); //$NON-NLS-1$
513:                         SWTDataElementIdHelper.setElementIdDataWithSubId(label, getVElement(), "control_label", //$NON-NLS-1$
514:                                 getViewModelContext());
515:                         label.setBackground(parent.getBackground());
516:
517:                         final EObject rootObject = getViewModelContext().getDomainModel();
518:                         try {
519:                                 final IObservableValue textObservable = WidgetProperties.text().observe(label);
520:                                 final IObservableValue displayNameObservable = labelProvider.getDisplayName(domainModelReference,
521:                                         rootObject);
522:                                 viewModelDBC.bindValue(textObservable, displayNameObservable, null, new UpdateValueStrategy() {
523:
524:                                         /**
525:                                          * {@inheritDoc}
526:                                          *
527:                                          * @see org.eclipse.core.databinding.UpdateValueStrategy#convert(java.lang.Object)
528:                                          */
529:                                         @Override
530:                                         public Object convert(Object value) {
531:                                                 String extra = ""; //$NON-NLS-1$
532:                                                 final VTMandatoryStyleProperty mandatoryStyle = getMandatoryStyle();
533:                                                 final EStructuralFeature structuralFeature = (EStructuralFeature) valueProperty.getValueType();
534:                                                 if (mandatoryStyle.isHighliteMandatoryFields() && structuralFeature.getLowerBound() > 0) {
535:                                                         extra = mandatoryStyle.getMandatoryMarker();
536:                                                 }
537:                                                 final String result = (String) super.convert(value);
538:                                                 return result + extra;
539:                                         }
540:
541:                                 });
542:                                 final IObservableValue tooltipObservable = WidgetProperties.tooltipText().observe(label);
543:                                 final IObservableValue descriptionObservable = labelProvider.getDescription(domainModelReference,
544:                                         rootObject);
545:                                 viewModelDBC.bindValue(tooltipObservable, descriptionObservable);
546:                         } catch (final NoLabelFoundException e) {
547:                                 // FIXME Expectations?
548:                                 getReportService().report(new RenderingFailedReport(e));
549:                         }
550:
551:                 }
552:                 return label;
553:         }
554:
555:         /**
556:          * @return the style bits for the control's label
557:          * @since 1.16
558:          */
559:         protected int getLabelStyleBits() {
560:                 return AbstractControlSWTRendererUtil
561:                         .getLabelStyleBits(getVTViewTemplateProvider(), getVElement(), getViewModelContext());
562:         }
563:
564:         /**
565:          * Whether the label for this control should be rendered on the left of the control. This is the case if the
566:          * {@link VControl#getLabelAlignment()} is set to {@link LabelAlignment#LEFT} or {@link LabelAlignment#DEFAULT}.
567:          *
568:          * @return <code>true</code> if label should be on the left, <code>false</code> otherwise
569:          * @since 1.7
570:          */
571:         protected boolean hasLeftLabelAlignment() {
572:•                return getVElement().getLabelAlignment() == LabelAlignment.LEFT
573:•                        || getVElement().getLabelAlignment() == LabelAlignment.DEFAULT;
574:         }
575:
576:         private VTMandatoryStyleProperty getMandatoryStyle() {
577:                 return AbstractControlSWTRendererUtil
578:                         .getMandatoryStyle(vtViewTemplateProvider, getVElement(), getViewModelContext());
579:         }
580:
581:         /**
582:          * Creates a validation icon.
583:          *
584:          * @param composite the {@link Composite} to create onto
585:          * @return the created Label
586:          */
587:         protected Label createValidationIcon(Composite composite) {
588:                 final Label validationLabel = new Label(composite, SWT.NONE);
589:                 SWTDataElementIdHelper.setElementIdDataWithSubId(validationLabel, getVElement(), "control_validation", //$NON-NLS-1$
590:                         getViewModelContext());
591:                 validationLabel.setBackground(composite.getBackground());
592:                 return validationLabel;
593:         }
594:
595:         /**
596:          * {@inheritDoc}
597:          *
598:          * @see org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer#applyEnable()
599:          * @since 1.6
600:          */
601:         @Override
602:         protected void applyEnable() {
603:•                for (final SWTGridCell gridCell : getControls().keySet()) {
604:                         try {
605:•                                final boolean observedNotNull = ((IObserving) getModelValue()).getObserved() != null;
606:•                                final boolean enabled = observedNotNull && getVElement().isEffectivelyEnabled();
607:                                 setControlEnabled(gridCell, getControls().get(gridCell), enabled);
608:•                                if (Boolean.FALSE.equals(enabled)) {
609:                                         getVElement().setDiagnostic(null);
610:                                 }
611:                         } catch (final DatabindingFailedException ex) {
612:                                 getReportService().report(new DatabindingFailedReport(ex));
613:                                 setControlEnabled(gridCell, getControls().get(gridCell), false);
614:                                 getVElement().setDiagnostic(null);
615:                         }
616:                 }
617:         }
618:
619:         /**
620:          * {@inheritDoc}
621:          *
622:          * @see org.eclipse.emfforms.spi.core.services.view.RootDomainModelChangeListener#notifyChange()
623:          * @since 1.9
624:          */
625:         @Override
626:         public void notifyChange() {
627:                 // TODO correct? - works so far
628:•                if (modelValue != null) {
629:                         modelValue.dispose();
630:                         modelValue = null;
631:                 }
632:
633:                 try {
634:                         rootDomainModelChanged();
635:                 } catch (final DatabindingFailedException ex) {
636:                         getReportService().report(new AbstractReport(ex, "Could not process the root domain model change.")); //$NON-NLS-1$
637:                 }
638:
639:         }
640:
641:         /**
642:          * This method is called in {@link #notifyChange()} when the root domain model of the view model context changes.
643:          *
644:          * @throws DatabindingFailedException If the databinding failed
645:          * @since 1.9
646:          */
647:         protected void rootDomainModelChanged() throws DatabindingFailedException {
648:         }
649:
650:         /**
651:          * {@inheritDoc}
652:          *
653:          * @see org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer#applyReadOnly()
654:          */
655:         @Override
656:         protected void applyReadOnly() {
657:•                for (final SWTGridCell gridCell : getControls().keySet()) {
658:•                        setControlEnabled(gridCell, getControls().get(gridCell), !getVElement().isEffectivelyReadonly());
659:                 }
660:         }
661: }