import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.TableEditor;
import org.simantics.modeling.userComponent.ComponentTypeCommands;
import org.simantics.scl.runtime.function.Function2;
import org.simantics.scl.runtime.function.Function4;
+import org.simantics.utils.threads.ThreadUtils;
import org.simantics.utils.ui.ErrorLogger;
public class ComponentTypeViewerData {
* Used to validate property names.
*/
public static final Pattern PROPERTY_NAME_PATTERN =
- Pattern.compile("([a-z]|_[0-9a-zA-Z_])[0-9a-zA-Z_]*");
+ Pattern.compile("([a-z]|_[0-9a-zA-Z_])[0-9a-zA-Z_]*"); //$NON-NLS-1$
public static final String[] PROPERTY_TYPE_SUGGESTIONS = new String[] {
- "Double",
- "Integer",
- "Float",
- "String",
- "Boolean",
- "Long",
- "[Double]",
- "[Integer]",
- "[Float]",
- "[String]",
- "[Boolean]",
- "[Long]",
- "Vector Double",
- "Vector Integer",
- "Vector Float",
- "Vector String",
- "Vector Boolean",
- "Vector Long"
+ "Double", //$NON-NLS-1$
+ "Integer", //$NON-NLS-1$
+ "Float", //$NON-NLS-1$
+ "String", //$NON-NLS-1$
+ "Boolean", //$NON-NLS-1$
+ "Long", //$NON-NLS-1$
+ "[Double]", //$NON-NLS-1$
+ "[Integer]", //$NON-NLS-1$
+ "[Float]", //$NON-NLS-1$
+ "[String]", //$NON-NLS-1$
+ "[Boolean]", //$NON-NLS-1$
+ "[Long]", //$NON-NLS-1$
+ "Vector Double", //$NON-NLS-1$
+ "Vector Integer", //$NON-NLS-1$
+ "Vector Float", //$NON-NLS-1$
+ "Vector String", //$NON-NLS-1$
+ "Vector Boolean", //$NON-NLS-1$
+ "Vector Long" //$NON-NLS-1$
};
-
+
public Resource componentType;
public FormToolkit tk;
public Form form;
public void editName(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column,
Pattern namePattern, DbConsumer<WriteGraph> extraWriter) {
editName(table, editor, propertyInfo, selectedItem, column,
+ null,
+ (pInfo, name) -> validatePropertyName(pInfo, name, namePattern),
+ extraWriter);
+ }
+
+ public void editName(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column,
+ Function2<ComponentTypeViewerPropertyInfo, String, String> nameFilter, Pattern namePattern, DbConsumer<WriteGraph> extraWriter) {
+ editName(table, editor, propertyInfo, selectedItem, column, nameFilter,
(pInfo, name) -> validatePropertyName(pInfo, name, namePattern),
extraWriter);
}
public void editName(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column,
Function2<ComponentTypeViewerPropertyInfo, String, String> nameValidator, DbConsumer<WriteGraph> extraWriter) {
+ editName(table, editor, propertyInfo, selectedItem, column, null, nameValidator, extraWriter);
+ }
+
+ public void editName(
+ Table table,
+ TableEditor editor,
+ final ComponentTypeViewerPropertyInfo propertyInfo,
+ TableItem selectedItem,
+ int column,
+ Function2<ComponentTypeViewerPropertyInfo, String, String> nameFilter,
+ Function2<ComponentTypeViewerPropertyInfo, String, String> nameValidator,
+ DbConsumer<WriteGraph> extraWriter) {
int extraStyle = propertyInfo.immutable ? SWT.READ_ONLY : 0;
final Text text = new Text(table, SWT.NONE | extraStyle);
org.eclipse.swt.widgets.Listener listener =
if (e.type == SWT.Dispose) {
form.setMessage(null);
return;
- }
-
- if (e.type == SWT.Modify) {
+ } else if (e.type == SWT.Verify) {
+ // Filter input if necessary
+ e.text = nameFilter != null ? nameFilter.apply(propertyInfo, e.text) : e.text;
+ return;
+ } else if (e.type == SWT.Modify) {
// validate current name
String error = nameValidator.apply(propertyInfo, text.getText());
if (error != null) {
form.setMessage(null);
}
return;
- }
-
- if (e.type == SWT.Traverse) {
+ } else if (e.type == SWT.Traverse) {
if (e.detail == SWT.TRAVERSE_ESCAPE) {
text.dispose();
e.doit = false;
graph.markUndoPoint();
Layer0 L0 = Layer0.getInstance(graph);
String prevName = graph.getPossibleRelatedValue2(propertyInfo.resource, L0.HasName);
- String oldCamelCasedLabel = prevName != null ? ComponentTypeCommands.camelCaseNameToLabel(prevName) : "";
+ String oldCamelCasedLabel = prevName != null ? ComponentTypeCommands.camelCaseNameToLabel(prevName) : ""; //$NON-NLS-1$
String oldLabel = graph.getPossibleRelatedValue(propertyInfo.resource, L0.HasLabel);
boolean setLabel = oldLabel == null
|| oldLabel.isEmpty()
});
}
};
+ if (nameFilter != null)
+ text.addListener(SWT.Verify, listener);
text.addListener(SWT.Modify, listener);
text.addListener(SWT.Deactivate, listener);
text.addListener(SWT.Traverse, listener);
combo.addListener(SWT.Traverse, listener);
}
- protected void editUnit(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column) {
+ public void editUnit(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column) {
// Disallow unit editing for non-numeric configuration properties
if (propertyInfo.numberType == null && propertyInfo.sectionSpecificData == null)
return;
if (validator != null) {
org.eclipse.swt.widgets.Listener validationListener = new org.eclipse.swt.widgets.Listener() {
+
+ private ScheduledFuture<?> future;
+
@Override
public void handleEvent(Event e) {
final String newValue = text.getText();
- String error = validator.apply(Simantics.getSession(), componentType, propertyInfo.resource, newValue);
- if (error != null) {
- text.setBackground(text.getDisplay().getSystemColor(SWT.COLOR_RED));
- text.setToolTipText(error);
- return;
- } else {
- text.setBackground(null);
- text.setToolTipText(null);
- }
+ if (future != null && !future.isCancelled())
+ future.cancel(true);
+ future = ThreadUtils.getNonBlockingWorkExecutor().schedule(() -> {
+ String error = validator.apply(Simantics.getSession(), componentType, propertyInfo.resource, newValue);
+ if (!text.isDisposed()) {
+ text.getDisplay().asyncExec(() -> {
+ if (!text.isDisposed()) {
+ if (error != null) {
+ text.setBackground(text.getDisplay().getSystemColor(SWT.COLOR_RED));
+ text.setToolTipText(error);
+ return;
+ } else {
+ text.setBackground(null);
+ text.setToolTipText(null);
+ }
+ }
+
+ });
+ }
+ }, 500, TimeUnit.MILLISECONDS);
}
};
text.addListener(SWT.Modify, validationListener);
private Range parseRange(NumberType numberType, String minStr, String maxStr, boolean lowInclusive, boolean highInclusive) throws RangeException {
try {
- String rangeStr = (lowInclusive ? "[" : "(") + minStr + ".." + maxStr + (highInclusive ? "]" : ")");
+ String rangeStr = (lowInclusive ? "[" : "(") + minStr + ".." + maxStr + (highInclusive ? "]" : ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
return Range.valueOf(rangeStr);
} catch (IllegalArgumentException e) {
// Limits are invalid
private static Combo createRangeInclusionCombo(Composite parent, boolean inclusive) {
Combo rng = new Combo(parent, SWT.READ_ONLY);
- rng.add("Inclusive");
- rng.add("Exclusive");
+ rng.add(Messages.ComponentTypeViewerData_Inclusive);
+ rng.add(Messages.ComponentTypeViewerData_Exclusive);
rng.select(inclusive ? 0 : 1);
return rng;
}
GridLayoutFactory.swtDefaults().numColumns(3).applyTo(composite);
Label low = new Label(composite, SWT.NONE);
- low.setText("Minimum Value:");
+ low.setText(Messages.ComponentTypeViewerData_MinimumValue);
final Text lowText = new Text(composite, SWT.BORDER | extraTextStyle);
GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).applyTo(lowText);
final Combo lowSelector = createRangeInclusionCombo(composite, !range.getLower().isExclusive());
Label high = new Label(composite, SWT.NONE);
- high.setText("Maximum Value:");
+ high.setText(Messages.ComponentTypeViewerData_MaximumValue);
final Text highText = new Text(composite, SWT.BORDER | extraTextStyle);
GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).applyTo(highText);
final Combo highSelector = createRangeInclusionCombo(composite, !range.getUpper().isExclusive());
GridLayoutFactory.swtDefaults().numColumns(2).equalWidth(true).applyTo(buttonComposite);
Button ok = new Button(buttonComposite, SWT.NONE);
- ok.setText("&OK");
+ ok.setText(IDialogConstants.OK_LABEL);
GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).applyTo(ok);
Button cancel = new Button(buttonComposite, SWT.NONE);
- cancel.setText("&Cancel");
+ cancel.setText(IDialogConstants.CANCEL_LABEL);
GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).applyTo(ok);
if (range.getLower().getValue() != null)
shell.open();
}
- protected void editMultilineText(Table table, TableEditor editor,
+ public void editMultilineText(Table table, TableEditor editor,
final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem,
Rectangle selectedItemBounds, int column, final StringWriter writer)
{
}
};
- String helpText = propertyInfo.immutable ? "ESC to close." : "Ctrl+Enter to apply changes, ESC to cancel.";
+ String helpText = propertyInfo.immutable ? Messages.ComponentTypeViewerData_ESCToClose : Messages.ComponentTypeViewerData_CtrlEnterApplyChanges;
Label help = tk.createLabel(shell, helpText, SWT.BORDER | SWT.FLAT);
GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(help);
- help.setForeground( tk.getColors().createColor( "fg", tk.getColors().getSystemColor(SWT.COLOR_LIST_SELECTION) ) );
+ help.setForeground( tk.getColors().createColor( "fg", tk.getColors().getSystemColor(SWT.COLOR_LIST_SELECTION) ) ); //$NON-NLS-1$
Display display = table.getDisplay();
Rectangle clientArea = display.getClientArea();
return null;
for (ComponentTypeViewerPropertyInfo info : properties) {
if (propertyName.equals(info.name))
- return "Property name '" + propertyName + "' is already in use.";
+ return NLS.bind(Messages.ComponentTypeViewerData_PropertyNameInUse, propertyName);
}
for (NamedResource cp : connectionPoints) {
if (propertyName.equals(cp.getName()))
- return "Name '" + propertyName + "' is already used for a terminal.";
+ return NLS.bind(Messages.ComponentTypeViewerData_NameInUse, propertyName );
}
Matcher m = namePattern.matcher(propertyName);
if (!m.matches())
- return "Property name '" + propertyName + "' contains invalid characters, does not match pattern "
- + namePattern.pattern() + ".";
+ return NLS.bind(Messages.ComponentTypeViewerData_ContainsInvalidCharacters, propertyName, namePattern.pattern());
return null;
}