Skip to content

Package: SWTControl$5

SWTControl$5

nameinstructionbranchcomplexitylinemethod
run()
M: 21 C: 5
19%
M: 3 C: 1
25%
M: 2 C: 1
33%
M: 4 C: 2
33%
M: 0 C: 1
100%
{...}
M: 0 C: 9
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-2013 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 Neufeld - initial API and implementation
13: *
14: *******************************************************************************/
15: package org.eclipse.emf.ecp.edit.internal.swt.util;
16:
17: import java.util.Collections;
18: import java.util.List;
19:
20: import org.eclipse.core.databinding.Binding;
21: import org.eclipse.core.databinding.observable.value.IObservableValue;
22: import org.eclipse.emf.common.util.Diagnostic;
23: import org.eclipse.emf.databinding.edit.EMFEditObservables;
24: import org.eclipse.emf.ecore.EStructuralFeature.Setting;
25: import org.eclipse.emf.ecp.edit.internal.swt.Activator;
26: import org.eclipse.emf.ecp.edit.spi.ECPAbstractControl;
27: import org.eclipse.emf.ecp.view.spi.model.VDiagnostic;
28: import org.eclipse.emf.ecp.view.spi.renderer.RenderingResultRow;
29: import org.eclipse.emf.edit.command.SetCommand;
30: import org.eclipse.emf.edit.domain.EditingDomain;
31: import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
32: import org.eclipse.emfforms.spi.swt.core.ui.SWTValidationHelper;
33: import org.eclipse.jface.action.Action;
34: import org.eclipse.jface.layout.GridDataFactory;
35: import org.eclipse.jface.layout.GridLayoutFactory;
36: import org.eclipse.swt.SWT;
37: import org.eclipse.swt.custom.StackLayout;
38: import org.eclipse.swt.events.DisposeEvent;
39: import org.eclipse.swt.events.DisposeListener;
40: import org.eclipse.swt.events.MouseEvent;
41: import org.eclipse.swt.events.MouseListener;
42: import org.eclipse.swt.events.SelectionAdapter;
43: import org.eclipse.swt.events.SelectionEvent;
44: import org.eclipse.swt.graphics.Color;
45: import org.eclipse.swt.graphics.Image;
46: import org.eclipse.swt.layout.GridLayout;
47: import org.eclipse.swt.widgets.Button;
48: import org.eclipse.swt.widgets.Composite;
49: import org.eclipse.swt.widgets.Control;
50: import org.eclipse.swt.widgets.Display;
51: import org.eclipse.swt.widgets.Label;
52:
53: /**
54: * This class defines a SWTCOntrol which is an abstract class defining an {@link ECPAbstractControl} for SWT.
55: *
56: * @author Eugen Neufeld
57: *
58: */
59: @Deprecated
60: public abstract class SWTControl extends ECPAbstractControl implements ECPControlSWT {
61:
62:         /**
63:          * RAP theming variable to set.
64:          */
65:         protected static final String CUSTOM_VARIANT = "org.eclipse.rap.rwt.customVariant";//$NON-NLS-1$
66:         /**
67:          * The icon for a validation error.
68:          */
69:         protected static final String VALIDATION_ERROR_ICON = "icons/validation_error.png";//$NON-NLS-1$
70:
71:         private static final String ICONS_UNSET_FEATURE = "icons/unset_feature.png"; //$NON-NLS-1$
72:
73:         /**
74:          * The label for the validation icon.
75:          */
76:         protected Label validationLabel;
77:
78:         private IObservableValue modelValue;
79:         private Binding binding;
80:
81:         private Composite controlComposite;
82:         private Composite parentComposite;
83:         private StackLayout sl;
84:         private Label unsetLabel;
85:
86:         /**
87:          *
88:          * {@inheritDoc}
89:          *
90:          * @see org.eclipse.emf.ecp.edit.internal.swt.util.ECPControlSWT#createControls(org.eclipse.swt.widgets.Composite)
91:          */
92:         @Override
93:         public List<RenderingResultRow<Control>> createControls(final Composite parent) {
94:                 final IItemPropertyDescriptor itemPropertyDescriptor = getItemPropertyDescriptor(getFirstSetting());
95:                 if (itemPropertyDescriptor == null) {
96:                         return null;
97:                 }
98:                 parent.addDisposeListener(new DisposeListener() {
99:
100:                         @Override
101:                         public void widgetDisposed(DisposeEvent e) {
102:                                 dispose();
103:                         }
104:                 });
105:                 createValidationIcon(parent);
106:                 final List<RenderingResultRow<Control>> list = Collections.singletonList(SWTRenderingHelper.INSTANCE
107:                         .getResultRowFactory().createRenderingResultRow(
108:                                 validationLabel, createControl(parent)));
109:
110:                 applyValidation(getControl().getDiagnostic());
111:
112:                 // TODO remove asap
113:                 backwardCompatibleHandleValidation();
114:
115:                 return list;
116:
117:         }
118:
119:         /**
120:          * This method is called to render the control on a parent.
121:          *
122:          * @param parent the {@link Composite} which is the parent
123:          * @return the created {@link Composite}
124:          */
125:         public Composite createControl(final Composite parent) {
126:
127:                 final Composite dataControl = createDataControl(parent);
128:
129:                 setHelpTooltips();
130:
131:                 // init
132:                 setEditable(isEditable());
133:
134:                 binding = bindValue();
135:
136:                 // write initial values to model (if they differ from the default value of the model-element)
137:                 if (!getFirstStructuralFeature().isUnsettable()
138:                         && !getFirstSetting().isSet()) {
139:                         if (binding != null) {
140:                                 binding.updateTargetToModel();
141:                         }
142:                 }
143:
144:                 return dataControl;
145:         }
146:
147:         private void createValidationIcon(Composite composite) {
148:                 if (!isEmbedded()) {
149:                         validationLabel = new Label(composite, SWT.NONE);
150:                         validationLabel.setBackground(composite.getBackground());
151:                         // set the size of the label to the size of the image
152:                         // GridDataFactory.fillDefaults().hint(16, 17).applyTo(validationLabel);
153:                 }
154:         }
155:
156:         private Composite createDataControl(Composite composite) {
157:                 final Composite innerComposite = new Composite(composite, SWT.NONE);
158:                 innerComposite.setBackground(composite.getBackground());
159:                 // GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.BEGINNING).applyTo(innerComposite);
160:                 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(innerComposite);
161:                 createContentControl(innerComposite);
162:                 return innerComposite;
163:         }
164:
165:         private void setHelpTooltips() {
166:                 final Control[] controls = getControlsForTooltip();
167:                 if (controls != null) {
168:                         for (final Control control : controls) {
169:                                 control.setToolTipText(getHelpText());
170:                         }
171:                 }
172:         }
173:
174:         /**
175:          * Method for retrieving all controls which should have the help text as their tooltip.
176:          *
177:          * @return the array of the controls to set a tooltip to
178:          */
179:         protected abstract Control[] getControlsForTooltip();
180:
181:         /**
182:          * Helper for creating the unset stacklayout and creating the control's composite.
183:          *
184:          * @param composite the parent {@link Composite} to create the control onto
185:          */
186:         protected void createContentControl(Composite composite) {
187:                 parentComposite = new Composite(composite, SWT.NONE);
188:                 parentComposite.setBackground(composite.getBackground());
189:                 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(parentComposite);
190:                 sl = new StackLayout();
191:                 parentComposite.setLayout(sl);
192:                 controlComposite = new Composite(parentComposite, SWT.NONE);
193:                 controlComposite.setBackground(parentComposite.getBackground());
194:
195:                 // 1 column for control, 1 for default unset button
196:                 GridLayoutFactory.fillDefaults().numColumns(1).spacing(2, 0)
197:                         .applyTo(controlComposite);
198:
199:                 unsetLabel = new Label(parentComposite, SWT.NONE);
200:                 unsetLabel.setBackground(composite.getBackground());
201:                 unsetLabel.setForeground(composite.getShell().getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
202:                 unsetLabel.setAlignment(SWT.CENTER);
203:                 unsetLabel.setText(getUnsetLabelText());
204:                 unsetLabel.addMouseListener(new MouseListener() {
205:
206:                         @Override
207:                         public void mouseUp(MouseEvent e) {
208:                                 sl.topControl = controlComposite;
209:                                 parentComposite.layout(true);
210:                                 if (binding != null) {
211:                                         binding.updateTargetToModel();
212:                                 } else {
213:                                         // TODO editingdomain is missing
214:                                         final Setting firstSetting = getFirstSetting();
215:                                         final Object currentUnsetValue = firstSetting.get(true);
216:                                         firstSetting.set(currentUnsetValue);
217:                                 }
218:                         }
219:
220:                         @Override
221:                         public void mouseDown(MouseEvent e) {
222:                                 // nothing to do
223:                         }
224:
225:                         @Override
226:                         public void mouseDoubleClick(MouseEvent e) {
227:                                 // nothing to do
228:                         }
229:                 });
230:                 int numControls = 1;
231:                 fillControlComposite(controlComposite);
232:
233:                 if (!isEmbedded() && getFirstStructuralFeature().isUnsettable()) {
234:                         Button unsetButton = getCustomUnsetButton();
235:                         if (unsetButton == null) {
236:                                 numControls++;
237:                                 unsetButton = new Button(controlComposite, SWT.PUSH);
238:                                 unsetButton.setToolTipText(getUnsetButtonTooltip());
239:                                 unsetButton.setImage(Activator.getImage(ICONS_UNSET_FEATURE));
240:                         }
241:                         unsetButton.addSelectionListener(new SelectionAdapter() {
242:                                 @Override
243:                                 public void widgetSelected(SelectionEvent e) {
244:                                         final Setting firstSetting = getFirstSetting();
245:                                         final EditingDomain editingDomain = getEditingDomain(firstSetting);
246:                                         editingDomain.getCommandStack()
247:                                                 .execute(
248:                                                         new SetCommand(editingDomain, firstSetting.getEObject(), firstSetting
249:                                                                 .getEStructuralFeature(), SetCommand.UNSET_VALUE));
250:
251:                                         showUnsetLabel();
252:                                 }
253:                         });
254:                         unsetButton.setData(CUSTOM_VARIANT, "org_eclipse_emf_ecp_control_unset"); //$NON-NLS-1$
255:                 }
256:                 if (numControls != 1) {
257:                         // 1 column for control, 1 for default unset button
258:                         ((GridLayout) controlComposite.getLayout()).numColumns = numControls;
259:                 }
260:
261:                 // INFO margin needed for controlDecorator
262:                 // .extendedMargins(10, 0, 0, 0)
263:
264:                 if (!getFirstStructuralFeature().isUnsettable()
265:                         || getFirstSetting().isSet()) {
266:                         sl.topControl = controlComposite;
267:                 } else {
268:                         sl.topControl = unsetLabel;
269:                 }
270:
271:                 parentComposite.layout();
272:         }
273:
274:         /**
275:          *
276:          */
277:         protected void showUnsetLabel() {
278:                 sl.topControl = unsetLabel;
279:                 parentComposite.layout();
280:         }
281:
282:         /**
283:          * This method must be overridden by concrete classes. Here the widget displaying the data is added to the
284:          * composite.
285:          *
286:          * @param controlComposite the {@link Composite} to add the widget to
287:          */
288:         protected abstract void fillControlComposite(Composite controlComposite);
289:
290:         /**
291:          * The default unset button will be displayed to the right of the control's composite. Concrete classes may override
292:          * this method to include an own unset button in their composite rather than using the default positioning.
293:          *
294:          * @return The custom unset button of the concrete class
295:          */
296:         protected Button getCustomUnsetButton() {
297:                 return null;
298:         }
299:
300:         /**
301:          * The model value used for databinding. It is either the set one or the calculated.
302:          *
303:          * @return the {@link IObservableValue}
304:          */
305:         protected IObservableValue getModelValue() {
306:                 if (modelValue != null) {
307:                         return modelValue;
308:                 }
309:                 final Setting setting = getFirstSetting();
310:                 modelValue = EMFEditObservables.observeValue(getEditingDomain(setting),
311:                         setting.getEObject(), setting.getEStructuralFeature());
312:                 return modelValue;
313:         }
314:
315:         /**
316:          * Allows the user to set the {@link IObservableValue} to use in the control during databinding.
317:          *
318:          * @param modelValue the set {@link IObservableValue}
319:          */
320:         public void setObservableValue(IObservableValue modelValue) {
321:                 this.modelValue = modelValue;
322:         }
323:
324:         /**
325:          * A helper method which creates a button for an action on a composite.
326:          *
327:          * @param action the action to create a button for
328:          * @param composite the composite to create the button onto
329:          * @return the created button
330:          */
331:         protected Button createButtonForAction(final Action action, final Composite composite) {
332:                 final Button selectButton = new Button(composite, SWT.PUSH);
333:                 selectButton.setImage(Activator.getImage(action));
334:                 selectButton.setEnabled(!getControl().isReadonly());
335:                 selectButton.setToolTipText(action.getToolTipText());
336:                 selectButton.addSelectionListener(new SelectionAdapter() {
337:                         @Override
338:                         public void widgetSelected(SelectionEvent e) {
339:                                 action.run();
340:                                 composite.layout();
341:                         }
342:
343:                 });
344:                 return selectButton;
345:         }
346:
347:         /**
348:          * Triggers the control to perform the databinding.
349:          *
350:          * @return The {@link Binding}
351:          */
352:         protected abstract Binding bindValue();
353:
354:         /**
355:          * Returns the help information.
356:          *
357:          * @return The help text
358:          */
359:         protected String getHelpText() {
360:                 return getItemPropertyDescriptor(getFirstSetting()).getDescription(null);
361:         }
362:
363:         /**
364:          * Returns the validation icon matching the given severity.
365:          *
366:          * @param severity the severity of the {@link org.eclipse.emf.common.util.Diagnostic}
367:          * @return the icon to be displayed, or <code>null</code> when no icon is to be displayed
368:          */
369:         protected Image getValidationIcon(int severity) {
370:                 return SWTValidationHelper.INSTANCE.getValidationIcon(severity);
371:         }
372:
373:         /**
374:          * Returns the background color for a control with the given validation severity.
375:          *
376:          * @param severity severity the severity of the {@link org.eclipse.emf.common.util.Diagnostic}
377:          * @return the color to be used as a background color
378:          */
379:         protected Color getValidationBackgroundColor(int severity) {
380:                 return SWTValidationHelper.INSTANCE.getValidationBackgroundColor(severity);
381:         }
382:
383:         /**
384:          * Returns the string for the unset label.
385:          *
386:          * @return The unset label text
387:          */
388:         protected abstract String getUnsetLabelText();
389:
390:         /**
391:          * Returns the string for the unset button tooltip.
392:          *
393:          * @return The unset button tooltip
394:          */
395:         protected abstract String getUnsetButtonTooltip();
396:
397:         /**
398:          * Method for retrieving a {@link Color} based on the predefined SWT id.
399:          *
400:          * @param color the SWT id of the color
401:          * @return the Color or black if the id was incorrect
402:          */
403:         protected final Color getSystemColor(int color) {
404:                 if (parentComposite == null) {
405:                         return Display.getDefault().getSystemColor(color);
406:                 }
407:                 return parentComposite.getShell().getDisplay().getSystemColor(color);
408:         }
409:
410:         /**
411:          * Whether this control should be editable.
412:          *
413:          * @return true if the {@link IItemPropertyDescriptor#canSetProperty(Object)} returns true, false otherwise
414:          */
415:         @Deprecated
416:         protected boolean isEditable() {
417:                 final Setting firstSetting = getFirstSetting();
418:                 return getItemPropertyDescriptor(firstSetting).canSetProperty(firstSetting.getEObject());
419:         }
420:
421:         @Override
422:         public void dispose() {
423:                 validationLabel = null;
424:                 if (modelValue != null) {
425:                         modelValue.dispose();
426:                         modelValue = null;
427:                 }
428:                 if (binding != null) {
429:                         binding.dispose();
430:                         binding = null;
431:                 }
432:                 if (controlComposite != null) {
433:                         controlComposite.dispose();
434:                         controlComposite = null;
435:                 }
436:                 if (parentComposite != null) {
437:                         parentComposite.dispose();
438:                         parentComposite = null;
439:                 }
440:                 sl = null;
441:                 if (unsetLabel != null) {
442:                         unsetLabel.dispose();
443:                         unsetLabel = null;
444:                 }
445:                 super.dispose();
446:         }
447:
448:         /**
449:          * Helper method to keep the old validation.
450:          *
451:          * @since 1.2
452:          */
453:         @Override
454:         protected void backwardCompatibleHandleValidation() {
455:                 final VDiagnostic diagnostic = getControl().getDiagnostic();
456:                 if (diagnostic == null) {
457:                         return;
458:                 }
459:                 Display.getDefault().asyncExec(new Runnable() {
460:                         @Override
461:                         public void run() {
462:•                                if (getControl() == null) {
463:                                         return;
464:                                 }
465:                                 resetValidation();
466:•                                for (final Object object : diagnostic.getDiagnostics()) {
467:                                         handleValidation((Diagnostic) object);
468:                                 }
469:                         }
470:                 });
471:         }
472: }