Bug 515821 - PreSetValidationService lacks combo support
Change-Id: I3d0f075891ebd52e49212014b7399fa4c729c44a
Signed-off-by: Mat Hansen <mhansen@eclipsesource.com>
diff --git a/bundles/org.eclipse.emf.ecp.edit.swt/src/org/eclipse/emf/ecp/edit/internal/swt/util/PreSetValidationListeners.java b/bundles/org.eclipse.emf.ecp.edit.swt/src/org/eclipse/emf/ecp/edit/internal/swt/util/PreSetValidationListeners.java
index 9848797..e39a6c0 100644
--- a/bundles/org.eclipse.emf.ecp.edit.swt/src/org/eclipse/emf/ecp/edit/internal/swt/util/PreSetValidationListeners.java
+++ b/bundles/org.eclipse.emf.ecp.edit.swt/src/org/eclipse/emf/ecp/edit/internal/swt/util/PreSetValidationListeners.java
@@ -29,6 +29,7 @@
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Text;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
@@ -44,8 +45,8 @@
/**
* Singleton instance.
*/
- private static PreSetValidationListeners instance = new PreSetValidationListeners();
- private PreSetValidationService preSetValidationService;
+ private static PreSetValidationListeners validationListeners = new PreSetValidationListeners();
+ private static PreSetValidationService preSetValidationService;
private PreSetValidationListeners() {
init();
@@ -57,7 +58,7 @@
* @return the factory that can be used to create and attach listeners
*/
public static PreSetValidationListeners create() {
- return instance;
+ return validationListeners;
}
private void init() {
@@ -86,6 +87,17 @@
}
/**
+ * Attach a {@link VerifyListener} to the given {@link Combo} widget.
+ * Performs pre-set validation for the given {@link EStructuralFeature}
+ *
+ * @param combo the combo widget the created verify listener should be attached to
+ * @param feature the feature to be validated
+ */
+ public void verify(Combo combo, final EStructuralFeature feature) {
+ verify(combo, feature, null);
+ }
+
+ /**
* Attach a {@link VerifyListener} to the given {@link Text} widget.
* Performs pre-set validation for the given {@link EStructuralFeature} and reports any
* errors to the given {@link VElement}.
@@ -109,7 +121,31 @@
}
}
- private VDiagnostic validateStrict(EStructuralFeature feature, Object value) {
+ /**
+ * Attach a {@link VerifyListener} to the given {@link Combo} widget.
+ * Performs pre-set validation for the given {@link EStructuralFeature} and reports any
+ * errors to the given {@link VElement}.
+ *
+ * @param combo the combo widget the created verify listener should be attached to
+ * @param feature the feature to be validated
+ * @param vElement the {@link VElement} an {@link Diagnostic} may be attached to
+ */
+ public void verify(Combo combo, final EStructuralFeature feature, final VElement vElement) {
+
+ if (!EAttribute.class.isInstance(feature)) {
+ // this shouldn't happen as we expect only EDataTypes
+ return;
+ }
+
+ final EAttribute attribute = (EAttribute) feature;
+
+ if (preSetValidationService != null) {
+ final VerifyListener verifyListener = new PreSetVerifyListener(vElement, attribute);
+ combo.addVerifyListener(verifyListener);
+ }
+ }
+
+ VDiagnostic validateStrict(EStructuralFeature feature, Object value) {
final Diagnostic strictDiag = preSetValidationService.validate(feature, value);
final VDiagnostic vDiagnostic = VViewFactory.eINSTANCE.createDiagnostic();
if (strictDiag.getSeverity() != Diagnostic.OK) {
@@ -130,84 +166,11 @@
return null;
}
- private boolean isString(EClassifier classifier) {
+ boolean isString(EClassifier classifier) {
return classifier.getInstanceTypeName().equals(String.class.getCanonicalName());
}
/**
- * Pre-set verify listener.
- *
- */
- class PreSetVerifyListener implements VerifyListener {
-
- private final EAttribute attribute;
- private final VElement vElement;
-
- /**
- * Constructor.
- *
- * @param vElement the {@link VElement} any {@link VDiagnostic} will be attached to
- * @param attribute the {@link EAttribute} to be validated
- */
- PreSetVerifyListener(VElement vElement, EAttribute attribute) {
- this.vElement = vElement;
- this.attribute = attribute;
- }
-
- @Override
- public void verifyText(VerifyEvent e) {
- final String changedText = obtainText(e);
-
- Object changedValue;
- try {
- changedValue = EcoreUtil.createFromString(attribute.getEAttributeType(), changedText);
- } catch (final IllegalArgumentException formatException) {
- if (isInteger(attribute.getEType()) && changedText.isEmpty()) {
- // TODO: corner case, let change propagate in case of integer
- return;
- }
-
- e.doit = false;
- return;
- }
-
- final VDiagnostic prevDiagnostic = vElement == null ? null : vElement.getDiagnostic();
- if (vElement != null) {
- vElement.setDiagnostic(validateStrict(attribute, changedValue));
- }
-
- final Diagnostic looseDiag = preSetValidationService.validateLoose(attribute, changedValue);
- if (looseDiag.getSeverity() == Diagnostic.OK) {
- // loose validation successfully, but keep nevertheless keep validation diagnostic
- return;
- }
-
- // loose validation not successfully, revert and restore previous diagnostic, if any
- // TODO: revert only for strings because of un-intuitive behavior for integers
- if (isString(attribute.getEType())) {
- // remove diagnostic once again, since we revert the change
- e.doit = false;
- if (vElement != null) {
- vElement.setDiagnostic(prevDiagnostic);
- }
-
- }
- }
-
- private String obtainText(VerifyEvent event) {
- final String currentText = Text.class.cast(event.widget).getText();
- final String changedText = currentText.substring(0, event.start) + event.text
- + currentText.substring(event.end);
- return changedText;
- }
-
- private boolean isInteger(EClassifier classifier) {
- return classifier.getInstanceTypeName().equals(Integer.class.getCanonicalName());
- }
-
- }
-
- /**
* Attach a {@link FocusListener} to the given {@link Text} widget.
* Performs pre-set validation for the given {@link EStructuralFeature} and
* executes the {@link Runnable} in case the content of the text widget is
@@ -235,4 +198,80 @@
});
}
}
+
+ public static class PreSetVerifyListener implements VerifyListener {
+
+ private final EAttribute attribute;
+ private final VElement vElement;
+
+ /**
+ * Constructor.
+ *
+ * @param vElement the {@link VElement} any {@link VDiagnostic} will be attached to
+ * @param attribute the {@link EAttribute} to be validated
+ * @param preSetValidationListeners TODO
+ */
+ public PreSetVerifyListener(VElement vElement, EAttribute attribute) {
+ this.vElement = vElement;
+ this.attribute = attribute;
+ }
+
+ @Override
+ public void verifyText(VerifyEvent e) {
+ final String changedText = obtainText(e);
+
+ Object changedValue;
+ try {
+ changedValue = EcoreUtil.createFromString(attribute.getEAttributeType(), changedText);
+ } catch (final IllegalArgumentException formatException) {
+ if (isInteger(attribute.getEType()) && changedText.isEmpty()) {
+ // TODO: corner case, let change propagate in case of integer
+ return;
+ }
+
+ e.doit = false;
+ return;
+ }
+
+ final VDiagnostic prevDiagnostic = vElement == null ? null : vElement.getDiagnostic();
+ if (vElement != null) {
+ vElement.setDiagnostic(validationListeners.validateStrict(attribute, changedValue));
+ }
+
+ final Diagnostic looseDiag = preSetValidationService.validateLoose(attribute,
+ changedValue);
+ if (looseDiag.getSeverity() == Diagnostic.OK) {
+ // loose validation successfully, but keep nevertheless keep validation diagnostic
+ return;
+ }
+
+ // loose validation not successfully, revert and restore previous diagnostic, if any
+ // TODO: revert only for strings because of un-intuitive behavior for integers
+ if (validationListeners.isString(attribute.getEType())) {
+ // remove diagnostic once again, since we revert the change
+ e.doit = false;
+ if (vElement != null) {
+ vElement.setDiagnostic(prevDiagnostic);
+ }
+
+ }
+ }
+
+ protected String obtainText(VerifyEvent event) {
+ String currentText = ""; //$NON-NLS-1$
+ if (event.widget instanceof Text) {
+ currentText = Text.class.cast(event.widget).getText();
+ } else if (event.widget instanceof Combo) {
+ currentText = Combo.class.cast(event.widget).getText();
+ }
+ final String changedText = currentText.substring(0, event.start) + event.text
+ + currentText.substring(event.end);
+ return changedText;
+ }
+
+ private boolean isInteger(EClassifier classifier) {
+ return classifier.getInstanceTypeName().equals(Integer.class.getCanonicalName());
+ }
+
+ }
}
diff --git a/bundles/org.eclipse.emfforms.common.prevalidation/src/org/eclipse/emfforms/internal/common/prevalidation/PreSetValidationServiceImpl.java b/bundles/org.eclipse.emfforms.common.prevalidation/src/org/eclipse/emfforms/internal/common/prevalidation/PreSetValidationServiceImpl.java
index fa0ed77..daec0c7 100644
--- a/bundles/org.eclipse.emfforms.common.prevalidation/src/org/eclipse/emfforms/internal/common/prevalidation/PreSetValidationServiceImpl.java
+++ b/bundles/org.eclipse.emfforms.common.prevalidation/src/org/eclipse/emfforms/internal/common/prevalidation/PreSetValidationServiceImpl.java
@@ -70,8 +70,11 @@
@Override
public boolean validate(EDataType eDataType, Object value, DiagnosticChain diagnostics,
Map<Object, Object> context) {
- final EValidator validator = EValidator.Registry.INSTANCE
+ EValidator validator = EValidator.Registry.INSTANCE
.getEValidator(eStructuralFeature.getEType().getEPackage());
+ if (validator == null) {
+ validator = new EObjectValidator();
+ }
return validator.validate(eDataType, value, diagnostics, context);
}
},