Skip to content

Package: DateTimeControlSWTRenderer$DateModelToTargetUpdateStrategy

DateTimeControlSWTRenderer$DateModelToTargetUpdateStrategy

nameinstructionbranchcomplexitylinemethod
DateTimeControlSWTRenderer.DateModelToTargetUpdateStrategy(DateTimeControlSWTRenderer)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
DateTimeControlSWTRenderer.DateModelToTargetUpdateStrategy(DateTimeControlSWTRenderer, int)
M: 7 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
doSet(IObservableValue, Object)
M: 0 C: 9
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
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: * Christian W. Damus - bug 527686
14: ******************************************************************************/
15: package org.eclipse.emf.ecp.view.internal.core.swt.renderer;
16:
17: import java.util.Calendar;
18: import java.util.Date;
19: import java.util.Locale;
20:
21: import javax.inject.Inject;
22:
23: import org.eclipse.core.databinding.Binding;
24: import org.eclipse.core.databinding.UpdateValueStrategy;
25: import org.eclipse.core.databinding.observable.IObserving;
26: import org.eclipse.core.databinding.observable.value.DateAndTimeObservableValue;
27: import org.eclipse.core.databinding.observable.value.IObservableValue;
28: import org.eclipse.core.runtime.IStatus;
29: import org.eclipse.core.runtime.Status;
30: import org.eclipse.emf.common.command.Command;
31: import org.eclipse.emf.ecore.EObject;
32: import org.eclipse.emf.ecore.EStructuralFeature;
33: import org.eclipse.emf.ecp.edit.spi.ViewLocaleService;
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.DateTimeDisplayType;
38: import org.eclipse.emf.ecp.view.spi.model.ModelChangeListener;
39: import org.eclipse.emf.ecp.view.spi.model.ModelChangeNotification;
40: import org.eclipse.emf.ecp.view.spi.model.VAttachment;
41: import org.eclipse.emf.ecp.view.spi.model.VControl;
42: import org.eclipse.emf.ecp.view.spi.model.VDateTimeDisplayAttachment;
43: import org.eclipse.emf.ecp.view.spi.util.swt.ImageRegistryService;
44: import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider;
45: import org.eclipse.emf.edit.command.SetCommand;
46: import org.eclipse.emfforms.spi.common.report.AbstractReport;
47: import org.eclipse.emfforms.spi.common.report.ReportService;
48: import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException;
49: import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedReport;
50: import org.eclipse.emfforms.spi.core.services.databinding.EMFFormsDatabinding;
51: import org.eclipse.emfforms.spi.core.services.label.EMFFormsLabelProvider;
52: import org.eclipse.emfforms.spi.localization.EMFFormsLocalizationService;
53: import org.eclipse.emfforms.spi.swt.core.SWTDataElementIdHelper;
54: import org.eclipse.jface.databinding.swt.ISWTObservableValue;
55: import org.eclipse.jface.databinding.swt.typed.WidgetProperties;
56: import org.eclipse.jface.dialogs.IDialogLabelKeys;
57: import org.eclipse.jface.layout.GridDataFactory;
58: import org.eclipse.jface.layout.GridLayoutFactory;
59: import org.eclipse.jface.resource.JFaceResources;
60: import org.eclipse.swt.SWT;
61: import org.eclipse.swt.custom.StackLayout;
62: import org.eclipse.swt.events.SelectionAdapter;
63: import org.eclipse.swt.events.SelectionEvent;
64: import org.eclipse.swt.graphics.Color;
65: import org.eclipse.swt.layout.GridData;
66: import org.eclipse.swt.layout.GridLayout;
67: import org.eclipse.swt.widgets.Button;
68: import org.eclipse.swt.widgets.Composite;
69: import org.eclipse.swt.widgets.Control;
70: import org.eclipse.swt.widgets.DateTime;
71: import org.eclipse.swt.widgets.Label;
72: import org.eclipse.swt.widgets.Shell;
73: import org.osgi.framework.FrameworkUtil;
74:
75: /**
76: * A control which can handle {@link java.util.Date Date}.
77: *
78: * @author Eugen Neufeld
79: *
80: */
81: public class DateTimeControlSWTRenderer extends SimpleControlSWTControlSWTRenderer {
82:
83:         /**
84:          * ModelToTarget Strategy that handles also null values of dates.
85:          *
86:          * @author Eugen Neufeld
87:          *
88:          */
89:         private class DateModelToTargetUpdateStrategy extends UpdateValueStrategy {
90:                 DateModelToTargetUpdateStrategy() {
91:                         super();
92:                 }
93:
94:                 DateModelToTargetUpdateStrategy(int policy) {
95:                         super(policy);
96:                 }
97:
98:                 @Override
99:                 protected IStatus doSet(IObservableValue observableValue, Object value) {
100:•                        if (value == null) {
101:                                 return Status.OK_STATUS;
102:                         }
103:                         return super.doSet(observableValue, value);
104:                 }
105:         }
106:
107:         private final EMFFormsLocalizationService localizationService;
108:
109:         private final ImageRegistryService imageRegistryService;
110:
111:         /**
112:          * Default constructor.
113:          *
114:          * @param vElement the view model element to be rendered
115:          * @param viewContext the view context
116:          * @param reportService The {@link ReportService}
117:          * @param emfFormsDatabinding The {@link EMFFormsDatabinding}
118:          * @param emfFormsLabelProvider The {@link EMFFormsLabelProvider}
119:          * @param vtViewTemplateProvider The {@link VTViewTemplateProvider}
120:          * @param localizationService The {@link EMFFormsLocalizationService}
121:          * @param imageRegistryService The {@link ImageRegistryService}
122:          */
123:         @Inject
124:         public DateTimeControlSWTRenderer(VControl vElement, ViewModelContext viewContext,
125:                 ReportService reportService,
126:                 EMFFormsDatabinding emfFormsDatabinding, EMFFormsLabelProvider emfFormsLabelProvider,
127:                 VTViewTemplateProvider vtViewTemplateProvider, EMFFormsLocalizationService localizationService,
128:                 ImageRegistryService imageRegistryService) {
129:                 super(vElement, viewContext, reportService, emfFormsDatabinding, emfFormsLabelProvider, vtViewTemplateProvider);
130:                 this.localizationService = localizationService;
131:                 this.imageRegistryService = imageRegistryService;
132:         }
133:
134:         private Label unsetLabel;
135:
136:         private StackLayout stackLayout;
137:
138:         private Composite stackComposite, dateTimeComposite;
139:
140:         private Composite composite;
141:
142:         private Shell dialog;
143:
144:         private ModelChangeListener domainModelChangeListener;
145:
146:         private DateTime dateWidget;
147:         private DateTime timeWidget;
148:
149:         private Button bUnset;
150:
151:         private Button setBtn;
152:
153:         @Override
154:         protected Binding[] createBindings(Control control) throws DatabindingFailedException {
155:                 final ISWTObservableValue dateObserver = WidgetProperties.dateTimeSelection().observe(dateWidget);
156:                 final ISWTObservableValue timeObserver = WidgetProperties.dateTimeSelection().observe(timeWidget);
157:                 final IObservableValue target = new DateAndTimeObservableValue(dateObserver, timeObserver);
158:                 final Binding binding = getDataBindingContext().bindValue(target, getModelValue(),
159:                         withPreSetValidation(new UpdateValueStrategy()),
160:                         new DateModelToTargetUpdateStrategy());
161:
162:                 if (domainModelChangeListener == null) {
163:                         domainModelChangeListener = new ModelChangeListener() {
164:                                 @Override
165:                                 public void notifyChange(ModelChangeNotification notification) {
166:                                         EStructuralFeature structuralFeature;
167:                                         try {
168:                                                 structuralFeature = (EStructuralFeature) getModelValue().getValueType();
169:                                         } catch (final DatabindingFailedException ex) {
170:                                                 getReportService().report(new DatabindingFailedReport(ex));
171:                                                 return;
172:                                         }
173:                                         if (structuralFeature.equals(notification.getStructuralFeature())) {
174:                                                 updateChangeListener(notification.getRawNotification().getNewValue());
175:                                         }
176:                                 }
177:                         };
178:                         getViewModelContext().registerDomainChangeListener(domainModelChangeListener);
179:                 }
180:
181:                 return new Binding[] { binding };
182:         }
183:
184:         /**
185:          * {@inheritDoc}
186:          *
187:          * @see org.eclipse.emf.ecp.view.spi.core.swt.SimpleControlSWTRenderer#dispose()
188:          */
189:         @Override
190:         protected void dispose() {
191:                 if (dialog != null && !dialog.isDisposed()) {
192:                         dialog.dispose();
193:                 }
194:                 getViewModelContext().unregisterDomainChangeListener(domainModelChangeListener);
195:                 super.dispose();
196:         }
197:
198:         @Override
199:         protected Control createSWTControl(Composite parent) throws DatabindingFailedException {
200:                 composite = new Composite(parent, SWT.NONE);
201:                 composite.setBackground(parent.getBackground());
202:                 GridLayoutFactory.fillDefaults().numColumns(2).spacing(2, 0).equalWidth(false)
203:                         .applyTo(composite);
204:                 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.BEGINNING).applyTo(composite);
205:
206:                 stackComposite = new Composite(composite, SWT.NONE);
207:                 stackComposite.setBackground(parent.getBackground());
208:                 GridLayoutFactory.fillDefaults().numColumns(1).spacing(2, 0).equalWidth(false)
209:                         .applyTo(stackComposite);
210:
211:                 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(stackComposite);
212:
213:                 dateTimeComposite = new Composite(stackComposite, SWT.NONE);
214:                 dateTimeComposite.setBackground(composite.getBackground());
215:                 GridLayoutFactory.fillDefaults().numColumns(3).spacing(2, 0).equalWidth(false)
216:                         .applyTo(dateTimeComposite);
217:                 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(dateTimeComposite);
218:
219:                 stackLayout = new StackLayout();
220:                 stackComposite.setLayout(stackLayout);
221:                 unsetLabel = new Label(stackComposite, SWT.CENTER);
222:                 SWTDataElementIdHelper.setElementIdDataWithSubId(unsetLabel, getVElement(), "unsetlabel", //$NON-NLS-1$
223:                         getViewModelContext());
224:                 unsetLabel.setText(getUnsetText());
225:                 unsetLabel.setBackground(stackComposite.getBackground());
226:                 unsetLabel.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
227:                 unsetLabel.setAlignment(SWT.CENTER);
228:
229:                 final DateTimeDisplayType dateTimeDisplayType = getDateTimeDisplayType();
230:                 createDateTimeWidgets(dateTimeDisplayType);
231:
232:                 bUnset = new Button(dateTimeComposite, SWT.PUSH);
233:                 SWTDataElementIdHelper.setElementIdDataWithSubId(bUnset, getVElement(), "unset", getViewModelContext()); //$NON-NLS-1$
234:                 GridDataFactory.fillDefaults().grab(false, false).align(SWT.CENTER, SWT.CENTER).applyTo(bUnset);
235:                 bUnset
236:                         .setImage(imageRegistryService.getImage(FrameworkUtil.getBundle(DateTimeControlSWTRenderer.class),
237:                                 "icons/unset_feature.png")); //$NON-NLS-1$
238:                 bUnset.setData(CUSTOM_VARIANT, "org_eclipse_emf_ecp_control_dateTime_buttonUnset"); //$NON-NLS-1$
239:                 final String tooltip = getDateTimeDisplayType() == DateTimeDisplayType.TIME_ONLY
240:                         ? MessageKeys.DateTimeControlSWTRenderer_CleanTime
241:                         : MessageKeys.DateTimeControlSWTRenderer_CleanDate;
242:                 bUnset.setToolTipText(getLocalizedString(tooltip));
243:                 bUnset.addSelectionListener(new UnsetBtnSelectionAdapterExtension());
244:
245:                 setBtn = createSetButton();
246:
247:                 updateStack();
248:                 return composite;
249:         }
250:
251:         @Override
252:         protected void applyReadOnly() {
253:                 super.applyReadOnly();
254:                 // specific handling for buttons
255:                 updateButtonVisibility();
256:         }
257:
258:         @Override
259:         protected void applyEnable() {
260:                 super.applyEnable();
261:                 // specific handling for buttons
262:                 updateButtonEnabling();
263:         }
264:
265:         /**
266:          * Updates the enablement of buttons according to the bound input.
267:          */
268:         protected void updateButtonEnabling() {
269:                 final boolean isEnable = getVElement().isEffectivelyEnabled() && !getVElement().isEffectivelyReadonly();
270:
271:                 if (bUnset != null) {
272:                         bUnset.setEnabled(isEnable);
273:                 }
274:                 if (setBtn != null) {
275:                         setBtn.setEnabled(isEnable);
276:                 }
277:         }
278:
279:         /**
280:          * Updates the visibility of buttons according to the bound input.
281:          */
282:         protected void updateButtonVisibility() {
283:                 final boolean isVisible = !getVElement().isEffectivelyReadonly() && !isUnchangeableFeature();
284:
285:                 if (bUnset != null) {
286:                         bUnset.setVisible(isVisible);
287:                         GridData.class.cast(bUnset.getLayoutData()).exclude = !isVisible;
288:                 }
289:
290:                 if (setBtn != null) {
291:                         try {
292:                                 if (getModelValue() != null) {
293:                                         final Object value = getModelValue().getValue();
294:
295:                                         if (getDateTimeDisplayType() == DateTimeDisplayType.TIME_ONLY) {
296:                                                 setBtn.setVisible(isVisible && value == null);
297:                                         } else {
298:                                                 setBtn.setVisible(isVisible);
299:                                         }
300:                                         GridData.class.cast(setBtn.getLayoutData()).exclude = !setBtn.isVisible();
301:                                 }
302:                         } catch (final DatabindingFailedException ex) {
303:                                 getReportService().report(new DatabindingFailedReport(ex));
304:                         }
305:                 }
306:
307:                 // Null check to avoid NPE during postInit
308:                 if (composite != null) {
309:                         composite.layout();
310:                 }
311:         }
312:
313:         private void updateStack() throws DatabindingFailedException {
314:                 final IObservableValue observableValue = getEMFFormsDatabinding()
315:                         .getObservableValue(getVElement().getDomainModelReference(), getViewModelContext().getDomainModel());
316:                 final EStructuralFeature structuralFeature = (EStructuralFeature) observableValue.getValueType();
317:                 final EObject eObject = (EObject) ((IObserving) observableValue).getObserved();
318:                 observableValue.dispose();
319:                 if (eObject.eIsSet(structuralFeature)) {
320:                         stackLayout.topControl = dateTimeComposite;
321:                 } else {
322:                         stackLayout.topControl = unsetLabel;
323:                 }
324:         }
325:
326:         private Button createSetButton() {
327:                 final String imagePath = getDateTimeDisplayType() == DateTimeDisplayType.TIME_ONLY ? "icons/set_feature.png" //$NON-NLS-1$
328:                         : "icons/date.png"; //$NON-NLS-1$
329:                 final Button setBtn = new Button(composite, SWT.PUSH);
330:                 SWTDataElementIdHelper.setElementIdDataWithSubId(setBtn, getVElement(), "set", getViewModelContext()); //$NON-NLS-1$
331:                 GridDataFactory.fillDefaults().grab(false, false).align(SWT.CENTER, SWT.CENTER).applyTo(setBtn);
332:                 setBtn.setImage(
333:                         imageRegistryService.getImage(FrameworkUtil.getBundle(DateTimeControlSWTRenderer.class), imagePath));
334:                 setBtn.setData(CUSTOM_VARIANT, "org_eclipse_emf_ecp_control_dateTime_buttonSet"); //$NON-NLS-1$
335:                 final String tooltip = getDateTimeDisplayType() == DateTimeDisplayType.TIME_ONLY
336:                         ? MessageKeys.DateTimeControlSWTRenderer_SelectTime
337:                         : MessageKeys.DateTimeControlSWTRenderer_SelectData;
338:                 setBtn.setToolTipText(getLocalizedString(tooltip));
339:                 setBtn.addSelectionListener(new SetBtnSelectionAdapterExtension(setBtn));
340:                 return setBtn;
341:         }
342:
343:         private void createDateTimeWidgets(DateTimeDisplayType dateTimeDisplayType) {
344:                 dateWidget = new DateTime(dateTimeComposite, SWT.DATE | SWT.BORDER);
345:                 SWTDataElementIdHelper.setElementIdDataWithSubId(dateWidget, getVElement(), "date", getViewModelContext()); //$NON-NLS-1$
346:                 dateWidget.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
347:                 dateWidget.setData(CUSTOM_VARIANT, "org_eclipse_emf_ecp_control_dateTime_date"); //$NON-NLS-1$
348:                 timeWidget = new DateTime(dateTimeComposite, SWT.TIME | SWT.SHORT | SWT.BORDER);
349:                 SWTDataElementIdHelper.setElementIdDataWithSubId(timeWidget, getVElement(), "time", getViewModelContext()); //$NON-NLS-1$
350:                 timeWidget.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
351:                 timeWidget.setData(CUSTOM_VARIANT, "org_eclipse_emf_ecp_control_dateTime_time"); //$NON-NLS-1$
352:                 if (dateTimeDisplayType == DateTimeDisplayType.TIME_ONLY) {
353:                         dateWidget.setVisible(false);
354:                         final GridData gridData = (GridData) dateWidget.getLayoutData();
355:                         gridData.exclude = true;
356:
357:                 }
358:                 if (dateTimeDisplayType == DateTimeDisplayType.DATE_ONLY) {
359:                         timeWidget.setVisible(false);
360:                         final GridData gridData = (GridData) timeWidget.getLayoutData();
361:                         gridData.exclude = true;
362:                 }
363:         }
364:
365:         /**
366:          * {@inheritDoc}
367:          *
368:          * @see org.eclipse.emf.ecp.view.spi.core.swt.SimpleControlSWTControlSWTRenderer#setValidationColor(org.eclipse.swt.widgets.Control,
369:          * org.eclipse.swt.graphics.Color)
370:          */
371:         @Override
372:         protected void setValidationColor(Control control, Color validationColor) {
373:                 ((Composite) control).getChildren()[0].setBackground(validationColor);
374:                 ((Composite) control).getChildren()[1].setBackground(validationColor);
375:         }
376:
377:         /**
378:          * {@inheritDoc}
379:          *
380:          * @see org.eclipse.emf.ecp.view.spi.core.swt.SimpleControlSWTRenderer#getUnsetText()
381:          */
382:         @Override
383:         protected String getUnsetText() {
384:                 final String text = getDateTimeDisplayType() == DateTimeDisplayType.TIME_ONLY
385:                         ? MessageKeys.DateTimeControl_NoTimeSetClickToSetTime
386:                         : MessageKeys.DateTimeControl_NoDateSetClickToSetDate;
387:                 return getLocalizedString(text);
388:         }
389:
390:         private String getLocalizedString(String key) {
391:                 return localizationService.getString(getClass(), key);
392:         }
393:
394:         /**
395:          * Set button adapter.
396:          */
397:         private class SetBtnSelectionAdapterExtension extends SelectionAdapter {
398:
399:                 private final Button btn;
400:
401:                 /**
402:                  * @param btn
403:                  * @param modelValue
404:                  * @param viewModelContext
405:                  */
406:                 SetBtnSelectionAdapterExtension(Button btn) {
407:                         this.btn = btn;
408:                 }
409:
410:                 @Override
411:                 public void widgetSelected(SelectionEvent e) {
412:                         if (getDateTimeDisplayType() == DateTimeDisplayType.TIME_ONLY) {
413:                                 setTime();
414:                         } else {
415:                                 setDate();
416:                         }
417:                 }
418:
419:                 private void setDate() {
420:                         if (dialog != null && !dialog.isDisposed()) {
421:                                 dialog.dispose();
422:                                 return;
423:                         }
424:                         final IObservableValue modelValue;
425:                         try {
426:                                 modelValue = getModelValue();
427:                         } catch (final DatabindingFailedException ex) {
428:                                 getReportService().report(new AbstractReport(ex));
429:                                 return;
430:                         }
431:                         dialog = new Shell(btn.getShell(), SWT.NONE);
432:                         dialog.setLayout(new GridLayout(1, false));
433:                         final DateTime calendar = new DateTime(dialog, SWT.CALENDAR | SWT.BORDER);
434:                         final IObservableValue calendarObserver = WidgetProperties.dateTimeSelection().observe(calendar);
435:                         final UpdateValueStrategy modelToTarget = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE);
436:
437:                         final Binding binding = getDataBindingContext().bindValue(calendarObserver, modelValue, modelToTarget,
438:                                 new DateModelToTargetUpdateStrategy(UpdateValueStrategy.POLICY_UPDATE));
439:                         final Calendar defaultCalendar = Calendar.getInstance(getLocale(getViewModelContext()));
440:                         final Date date = (Date) modelValue.getValue();
441:                         if (date != null) {
442:                                 defaultCalendar.setTime(date);
443:                         }
444:                         calendar.setDate(defaultCalendar.get(Calendar.YEAR), defaultCalendar.get(Calendar.MONTH),
445:                                 defaultCalendar.get(Calendar.DAY_OF_MONTH));
446:
447:                         final Button okButton = new Button(dialog, SWT.PUSH);
448:                         okButton.setText(JFaceResources.getString(IDialogLabelKeys.OK_LABEL_KEY));
449:                         GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).grab(false, false).applyTo(okButton);
450:                         okButton.addSelectionListener(new SelectionAdapter() {
451:                                 /**
452:                                  * {@inheritDoc}
453:                                  *
454:                                  * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
455:                                  */
456:                                 @Override
457:                                 public void widgetSelected(SelectionEvent e) {
458:                                         binding.updateTargetToModel();
459:                                         binding.dispose();
460:                                         dialog.close();
461:                                         updateChangeListener(modelValue.getValue());
462:                                 }
463:                         });
464:
465:                         dialog.pack();
466:                         dialog.layout();
467:                         dialog.setLocation(btn.getParent().toDisplay(
468:                                 btn.getLocation().x + btn.getSize().x - dialog.getSize().x,
469:                                 btn.getLocation().y + btn.getSize().y));
470:                         dialog.open();
471:
472:                 }
473:
474:                 private void setTime() {
475:                         try {
476:                                 final EStructuralFeature structuralFeature = (EStructuralFeature) getModelValue().getValueType();
477:                                 final EObject eObject = (EObject) ((IObserving) getModelValue()).getObserved();
478:                                 final Command setCommand = SetCommand.create(getEditingDomain(eObject), eObject, structuralFeature,
479:                                         new Date());
480:                                 getEditingDomain(eObject).getCommandStack().execute(setCommand);
481:                                 updateChangeListener(getModelValue().getValue());
482:                         } catch (final DatabindingFailedException ex) {
483:                                 getReportService().report(new DatabindingFailedReport(ex));
484:                         }
485:                 }
486:
487:         }
488:
489:         /**
490:          * Unset button adapter.
491:          */
492:         private class UnsetBtnSelectionAdapterExtension extends SelectionAdapter {
493:
494:                 @Override
495:                 public void widgetSelected(SelectionEvent e) {
496:                         try {
497:                                 final EStructuralFeature structuralFeature = (EStructuralFeature) getModelValue().getValueType();
498:                                 final EObject eObject = (EObject) ((IObserving) getModelValue()).getObserved();
499:                                 final Command removeCommand = SetCommand.create(getEditingDomain(eObject), eObject, structuralFeature,
500:                                         null);
501:                                 getEditingDomain(eObject).getCommandStack().execute(removeCommand);
502:                                 updateChangeListener(getModelValue().getValue());
503:                         } catch (final DatabindingFailedException ex) {
504:                                 getReportService().report(new DatabindingFailedReport(ex));
505:                                 // Do nothing. This should not happen because if getModelValue() fails, the control will never be
506:                                 // rendered and consequently this code will never be executed.
507:                         }
508:                 }
509:
510:         }
511:
512:         private Locale getLocale(ViewModelContext viewModelContext) {
513:                 final ViewLocaleService service = viewModelContext.getService(ViewLocaleService.class);
514:                 if (service == null) {
515:                         return Locale.getDefault();
516:                 }
517:                 return service.getLocale();
518:         }
519:
520:         private void updateChangeListener(Object value) {
521:                 if (value == null) {
522:                         if (stackLayout.topControl != unsetLabel) {
523:                                 stackLayout.topControl = unsetLabel;
524:                                 stackComposite.layout();
525:                         }
526:
527:                 } else {
528:                         if (stackLayout.topControl != dateTimeComposite) {
529:                                 stackLayout.topControl = dateTimeComposite;
530:                                 stackComposite.layout();
531:                         }
532:                 }
533:                 updateButtonVisibility();
534:                 if (!ignoreEnableOnReadOnly()) {
535:                         applyEnable();
536:                 }
537:         }
538:
539:         private DateTimeDisplayType getDateTimeDisplayType() {
540:                 if (getVElement() != null && getVElement().getAttachments() != null) {
541:                         for (final VAttachment attachment : getVElement().getAttachments()) {
542:                                 if (VDateTimeDisplayAttachment.class.isInstance(attachment)) {
543:                                         final VDateTimeDisplayAttachment dateTimeAttachment = (VDateTimeDisplayAttachment) attachment;
544:                                         return dateTimeAttachment.getDisplayType();
545:                                 }
546:                         }
547:                 }
548:                 return DateTimeDisplayType.TIME_AND_DATE;
549:         }
550:
551:         /**
552:          * {@inheritDoc}
553:          *
554:          * @see org.eclipse.emf.ecp.view.spi.core.swt.SimpleControlSWTControlSWTRenderer#rootDomainModelChanged()
555:          */
556:         @Override
557:         protected void rootDomainModelChanged() throws DatabindingFailedException {
558:                 super.rootDomainModelChanged();
559:                 updateStack();
560:                 stackComposite.layout();
561:         }
562: }