1 package org.simantics.modeling.ui.componentTypeEditor;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Collections;
6 import java.util.HashSet;
9 import java.util.concurrent.ScheduledFuture;
10 import java.util.concurrent.TimeUnit;
11 import java.util.regex.Matcher;
12 import java.util.regex.Pattern;
14 import org.eclipse.jface.dialogs.IDialogConstants;
15 import org.eclipse.jface.dialogs.IMessageProvider;
16 import org.eclipse.jface.layout.GridDataFactory;
17 import org.eclipse.jface.layout.GridLayoutFactory;
18 import org.eclipse.osgi.util.NLS;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.custom.StyledText;
21 import org.eclipse.swt.custom.TableEditor;
22 import org.eclipse.swt.events.SelectionAdapter;
23 import org.eclipse.swt.events.SelectionEvent;
24 import org.eclipse.swt.graphics.Point;
25 import org.eclipse.swt.graphics.Rectangle;
26 import org.eclipse.swt.widgets.Button;
27 import org.eclipse.swt.widgets.Combo;
28 import org.eclipse.swt.widgets.Composite;
29 import org.eclipse.swt.widgets.Display;
30 import org.eclipse.swt.widgets.Event;
31 import org.eclipse.swt.widgets.Label;
32 import org.eclipse.swt.widgets.Shell;
33 import org.eclipse.swt.widgets.Table;
34 import org.eclipse.swt.widgets.TableItem;
35 import org.eclipse.swt.widgets.Text;
36 import org.eclipse.ui.forms.widgets.Form;
37 import org.eclipse.ui.forms.widgets.FormToolkit;
38 import org.simantics.Simantics;
39 import org.simantics.databoard.Bindings;
40 import org.simantics.databoard.type.NumberType;
41 import org.simantics.databoard.units.internal.library.UnitLibrary;
42 import org.simantics.databoard.util.Limit;
43 import org.simantics.databoard.util.Range;
44 import org.simantics.databoard.util.RangeException;
45 import org.simantics.db.RequestProcessor;
46 import org.simantics.db.Resource;
47 import org.simantics.db.Statement;
48 import org.simantics.db.WriteGraph;
49 import org.simantics.db.common.NamedResource;
50 import org.simantics.db.common.request.IndexRoot;
51 import org.simantics.db.common.request.WriteRequest;
52 import org.simantics.db.exception.DatabaseException;
53 import org.simantics.db.function.DbConsumer;
54 import org.simantics.db.layer0.QueryIndexUtils;
55 import org.simantics.layer0.Layer0;
56 import org.simantics.modeling.ModelingResources;
57 import org.simantics.modeling.userComponent.ComponentTypeCommands;
58 import org.simantics.modeling.utils.ComponentTypeViewerPropertyInfo;
59 import org.simantics.scl.runtime.function.Function2;
60 import org.simantics.scl.runtime.function.Function4;
61 import org.simantics.utils.datastructures.Pair;
62 import org.simantics.utils.threads.ThreadUtils;
63 import org.simantics.utils.ui.ErrorLogger;
65 public class ComponentTypeViewerData {
67 * Used to validate property names.
69 public static final Pattern PROPERTY_NAME_PATTERN =
70 Pattern.compile("([a-z]|_[0-9a-zA-Z_])[0-9a-zA-Z_]*"); //$NON-NLS-1$
72 public static final String[] PROPERTY_TYPE_SUGGESTIONS = new String[] {
73 "Double", //$NON-NLS-1$
74 "Integer", //$NON-NLS-1$
75 "Float", //$NON-NLS-1$
76 "String", //$NON-NLS-1$
77 "Boolean", //$NON-NLS-1$
79 "[Double]", //$NON-NLS-1$
80 "[Integer]", //$NON-NLS-1$
81 "[Float]", //$NON-NLS-1$
82 "[String]", //$NON-NLS-1$
83 "[Boolean]", //$NON-NLS-1$
84 "[Long]", //$NON-NLS-1$
85 "Vector Double", //$NON-NLS-1$
86 "Vector Integer", //$NON-NLS-1$
87 "Vector Float", //$NON-NLS-1$
88 "Vector String", //$NON-NLS-1$
89 "Vector Boolean", //$NON-NLS-1$
90 "Vector Long" //$NON-NLS-1$
93 public Resource componentType;
94 public FormToolkit tk;
96 public UnitLibrary unitLibrary = UnitLibrary.createDefault();
97 public boolean readOnly;
98 public NamedResource[] connectionPoints;
99 public ComponentTypeViewerPropertyInfo[] properties;
101 public ComponentTypeViewerData(FormToolkit tk, Resource componentType, Form form) {
103 this.componentType = componentType;
107 public void editName(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column,
108 Pattern namePattern) {
109 editName(table, editor, propertyInfo, selectedItem, column, namePattern, null);
112 public void editName(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column,
113 Pattern namePattern, DbConsumer<WriteGraph> extraWriter) {
114 editName(table, editor, propertyInfo, selectedItem, column,
116 (pInfo, name) -> validatePropertyName(pInfo, name, namePattern),
120 public void editName(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column,
121 Function2<ComponentTypeViewerPropertyInfo, String, String> nameFilter, Pattern namePattern, DbConsumer<WriteGraph> extraWriter) {
122 editName(table, editor, propertyInfo, selectedItem, column, nameFilter,
123 (pInfo, name) -> validatePropertyName(pInfo, name, namePattern),
127 public void editName(Table table, TableEditor editor, ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column,
128 Function2<ComponentTypeViewerPropertyInfo, String, String> nameValidator)
130 editName(table, editor, propertyInfo, selectedItem, column, nameValidator, null);
133 public void editName(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column,
134 Function2<ComponentTypeViewerPropertyInfo, String, String> nameValidator, DbConsumer<WriteGraph> extraWriter) {
135 editName(table, editor, propertyInfo, selectedItem, column, null, nameValidator, extraWriter);
138 public void editName(
141 final ComponentTypeViewerPropertyInfo propertyInfo,
142 TableItem selectedItem,
144 Function2<ComponentTypeViewerPropertyInfo, String, String> nameFilter,
145 Function2<ComponentTypeViewerPropertyInfo, String, String> nameValidator,
146 DbConsumer<WriteGraph> extraWriter) {
147 int extraStyle = propertyInfo.immutable ? SWT.READ_ONLY : 0;
148 final Text text = new Text(table, SWT.NONE | extraStyle);
149 org.eclipse.swt.widgets.Listener listener =
150 new org.eclipse.swt.widgets.Listener() {
152 public void handleEvent(Event e) {
153 if (e.type == SWT.Dispose) {
154 form.setMessage(null);
156 } else if (e.type == SWT.Verify) {
157 // Filter input if necessary
158 e.text = nameFilter != null ? nameFilter.apply(propertyInfo, e.text) : e.text;
160 } else if (e.type == SWT.Modify) {
161 // validate current name
162 String error = nameValidator.apply(propertyInfo, text.getText());
164 text.setBackground(text.getDisplay().getSystemColor(SWT.COLOR_RED));
165 form.setMessage(error, IMessageProvider.ERROR);
167 text.setBackground(null);
168 form.setMessage(null);
171 } else if (e.type == SWT.Traverse) {
172 if (e.detail == SWT.TRAVERSE_ESCAPE) {
177 if (e.detail == SWT.TRAVERSE_ARROW_NEXT || e.detail == SWT.TRAVERSE_ARROW_PREVIOUS || e.detail == SWT.TRAVERSE_MNEMONIC)
181 final String newValue = text.getText();
184 String error = nameValidator.apply(propertyInfo, newValue);
188 if (propertyInfo.immutable)
191 Simantics.getSession().async(new WriteRequest() {
193 public void perform(WriteGraph graph)
194 throws DatabaseException {
195 graph.markUndoPoint();
196 Layer0 L0 = Layer0.getInstance(graph);
197 String prevName = graph.getPossibleRelatedValue2(propertyInfo.resource, L0.HasName);
198 String oldCamelCasedLabel = prevName != null ? ComponentTypeCommands.camelCaseNameToLabel(prevName) : ""; //$NON-NLS-1$
199 String oldLabel = graph.getPossibleRelatedValue(propertyInfo.resource, L0.HasLabel);
200 boolean setLabel = oldLabel == null
201 || oldLabel.isEmpty()
202 || oldCamelCasedLabel.isEmpty()
203 || oldCamelCasedLabel.equals(oldLabel);
205 ComponentTypeCommands.rename(graph, propertyInfo.resource, newValue);
207 ComponentTypeCommands.setLabel(graph, propertyInfo.resource, ComponentTypeCommands.camelCaseNameToLabel(newValue));
209 if (extraWriter != null)
210 extraWriter.accept(graph);
215 if (nameFilter != null)
216 text.addListener(SWT.Verify, listener);
217 text.addListener(SWT.Modify, listener);
218 text.addListener(SWT.Deactivate, listener);
219 text.addListener(SWT.Traverse, listener);
220 text.addListener(SWT.Dispose, listener);
222 text.setText(selectedItem.getText(column));
226 editor.setEditor(text, selectedItem, column);
229 public void editType(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column, String range, final boolean convertDefaultValue) {
230 int extraStyle = propertyInfo.immutable ? SWT.READ_ONLY : 0;
231 final Combo combo = new Combo(table, SWT.NONE | extraStyle);
232 combo.setText(selectedItem.getText(column));
233 for(String suggestion : PROPERTY_TYPE_SUGGESTIONS)
234 combo.add(suggestion);
235 org.eclipse.swt.widgets.Listener listener =
236 new org.eclipse.swt.widgets.Listener() {
238 public void handleEvent(Event e) {
239 if(e.type == SWT.Traverse) {
240 if (e.detail == SWT.TRAVERSE_ESCAPE) {
245 if (e.detail == SWT.TRAVERSE_ARROW_NEXT
246 || e.detail == SWT.TRAVERSE_ARROW_PREVIOUS
247 || e.detail == SWT.TRAVERSE_MNEMONIC)
250 final String newValue = combo.getText();
251 if (e.type == SWT.Traverse) {
256 if (propertyInfo.immutable)
260 Simantics.getSession().async(new WriteRequest() {
262 public void perform(WriteGraph graph)
263 throws DatabaseException {
264 graph.markUndoPoint();
266 String newValue2 = newValue;
268 Resource possibleGraphType = null;
270 Layer0 L0 = Layer0.getInstance(graph);
271 ModelingResources MOD = ModelingResources.getInstance(graph);
273 Resource previousRange = graph.getPossibleObject(propertyInfo.resource, L0.HasRange);
274 if (previousRange != null && graph.isInheritedFrom(previousRange, MOD.MonitorValue)) {
275 // Do not override range of derived properties
276 possibleGraphType = previousRange;
278 Resource root = graph.syncRequest(new IndexRoot(componentType));
280 Resource L0Res = graph.getResource("http://www.simantics.org/Layer0-1.1");
282 Collection<Resource> graphTypes1 = QueryIndexUtils.searchByTypeAndName(graph, L0Res, L0.ValueType, newValue);
283 Collection<Resource> graphTypes2 = QueryIndexUtils.searchByTypeAndName(graph, root, L0.ValueType, newValue);
285 Collection<Resource> graphTypes = new HashSet<>(graphTypes1);
286 graphTypes.addAll(graphTypes2);
288 Set<Pair<Resource, String>> candidates = new HashSet<>();
289 for (Resource graphType : graphTypes) {
290 Collection<Statement> stms = graph.getAssertedStatements(graphType, L0.HasValueType);
291 if(stms.size() == 1) {
292 // Only accept valueType if it asserts HasValueType with the same name
293 String hasValueType = graph.getValue(stms.iterator().next().getObject(), Bindings.STRING);
294 if (hasValueType.equals(newValue)) {
295 candidates.add(new Pair<>(graphType, hasValueType));
300 // We support only graph types with unique name at this point. Later we could implement UI to let the user to select from multiple graph types.
301 if (candidates.size() == 1) {
302 Pair<Resource, String> result = candidates.iterator().next();
303 possibleGraphType = result.first;
304 newValue2 = result.second;
308 ComponentTypeCommands.editType(graph, componentType, propertyInfo.resource, convertDefaultValue, newValue2, possibleGraphType);
309 if (range != null) ComponentTypeCommands.setRange(graph, componentType, propertyInfo.resource, range);
315 editor.setEditor(combo, selectedItem, column);
316 combo.addListener(SWT.FocusOut, listener);
317 combo.addListener(SWT.Traverse, listener);
320 public void editUnit(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column) {
321 // Disallow unit editing for non-numeric configuration properties
322 if (propertyInfo.numberType == null && propertyInfo.sectionSpecificData == null)
325 int extraStyle = propertyInfo.immutable ? SWT.READ_ONLY : 0;
326 final Combo combo = new Combo(table, SWT.NONE | extraStyle);
327 String initialValue = selectedItem.getText(column);
328 List<String> units = new ArrayList<>( unitLibrary.getUnits() );
329 Collections.sort(units, String.CASE_INSENSITIVE_ORDER);
332 for (String unit : units) {
334 if (unit.equals(initialValue))
338 combo.setText(initialValue);
340 org.eclipse.swt.widgets.Listener listener =
341 new org.eclipse.swt.widgets.Listener() {
343 public void handleEvent(Event e) {
344 if(e.type == SWT.Traverse) {
345 if (e.detail == SWT.TRAVERSE_ESCAPE) {
350 if (e.detail == SWT.TRAVERSE_ARROW_NEXT
351 || e.detail == SWT.TRAVERSE_ARROW_PREVIOUS
352 || e.detail == SWT.TRAVERSE_MNEMONIC)
355 final String newValue = combo.getText();
356 if(e.type == SWT.Traverse) {
361 if (propertyInfo.immutable)
364 Simantics.getSession().async(new WriteRequest() {
366 public void perform(WriteGraph graph)
367 throws DatabaseException {
368 graph.markUndoPoint();
369 ComponentTypeCommands.setUnit(graph, componentType, propertyInfo.resource, newValue);
375 editor.setEditor(combo, selectedItem, column);
376 combo.addListener(SWT.Deactivate, listener);
377 combo.addListener(SWT.Traverse, listener);
380 public void editValue(Table table, TableEditor editor,
381 final ComponentTypeViewerPropertyInfo propertyInfo,
382 TableItem selectedItem, int column,
383 final StringWriter writer,
384 final Function4<RequestProcessor, Resource, Resource, String, String> validator)
386 int extraStyle = writer == null ? SWT.READ_ONLY : 0;
387 final Text text = new Text(table, SWT.NONE | extraStyle);
388 text.setText(selectedItem.getText(column));
389 org.eclipse.swt.widgets.Listener listener =
390 new org.eclipse.swt.widgets.Listener() {
392 public void handleEvent(Event e) {
393 if(e.type == SWT.Traverse) {
394 if (e.detail == SWT.TRAVERSE_ESCAPE) {
399 if (e.detail == SWT.TRAVERSE_ARROW_NEXT
400 || e.detail == SWT.TRAVERSE_ARROW_PREVIOUS
401 || e.detail == SWT.TRAVERSE_MNEMONIC)
404 final String newValue = text.getText();
405 if(e.type == SWT.Traverse) {
410 if (validator != null) {
411 String error = validator.apply(Simantics.getSession(), componentType, propertyInfo.resource, newValue);
416 if (writer != null) {
417 Simantics.getSession().async(new WriteRequest() {
419 public void perform(WriteGraph graph) throws DatabaseException {
420 writer.perform(graph, newValue);
428 editor.setEditor(text, selectedItem, column);
429 text.addListener(SWT.FocusOut, listener);
430 text.addListener(SWT.Traverse, listener);
432 if (validator != null) {
433 org.eclipse.swt.widgets.Listener validationListener = new org.eclipse.swt.widgets.Listener() {
435 private ScheduledFuture<?> future;
438 public void handleEvent(Event e) {
439 final String newValue = text.getText();
440 if (future != null && !future.isCancelled())
442 future = ThreadUtils.getNonBlockingWorkExecutor().schedule(() -> {
443 String error = validator.apply(Simantics.getSession(), componentType, propertyInfo.resource, newValue);
444 if (!text.isDisposed()) {
445 text.getDisplay().asyncExec(() -> {
446 if (!text.isDisposed()) {
448 text.setBackground(text.getDisplay().getSystemColor(SWT.COLOR_RED));
449 text.setToolTipText(error);
452 text.setBackground(null);
453 text.setToolTipText(null);
459 }, 500, TimeUnit.MILLISECONDS);
462 text.addListener(SWT.Modify, validationListener);
466 private Range parseRange(NumberType numberType, String minStr, String maxStr, boolean lowInclusive, boolean highInclusive) throws RangeException {
468 String rangeStr = (lowInclusive ? "[" : "(") + minStr + ".." + maxStr + (highInclusive ? "]" : ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
469 return Range.valueOf(rangeStr);
470 } catch (IllegalArgumentException e) {
471 // Limits are invalid
472 throw new RangeException(e.getMessage(), e);
476 private static Combo createRangeInclusionCombo(Composite parent, boolean inclusive) {
477 Combo rng = new Combo(parent, SWT.READ_ONLY);
478 rng.add(Messages.ComponentTypeViewerData_Inclusive);
479 rng.add(Messages.ComponentTypeViewerData_Exclusive);
480 rng.select(inclusive ? 0 : 1);
484 protected void editRange(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, Rectangle selectedItemBounds, int column) {
485 // Disallow range editing when the property is not numeric
486 if (propertyInfo.numberType == null)
489 int extraTextStyle = propertyInfo.immutable ? SWT.READ_ONLY : 0;
491 // Parse initial range value
493 String rangeStr = selectedItem.getText(column);
495 range = Range.valueOf(rangeStr);
496 } catch (RangeException ex) {
497 range = new Range(Limit.nolimit(), Limit.nolimit());
500 final Shell shell = new Shell(table.getShell(), SWT.ON_TOP);
501 GridLayoutFactory.fillDefaults().applyTo(shell);
503 Composite composite = new Composite(shell, SWT.NONE);
504 GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);
505 GridLayoutFactory.swtDefaults().numColumns(3).applyTo(composite);
507 Label low = new Label(composite, SWT.NONE);
508 low.setText(Messages.ComponentTypeViewerData_MinimumValue);
509 final Text lowText = new Text(composite, SWT.BORDER | extraTextStyle);
510 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).applyTo(lowText);
511 final Combo lowSelector = createRangeInclusionCombo(composite, !range.getLower().isExclusive());
512 Label high = new Label(composite, SWT.NONE);
513 high.setText(Messages.ComponentTypeViewerData_MaximumValue);
514 final Text highText = new Text(composite, SWT.BORDER | extraTextStyle);
515 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).applyTo(highText);
516 final Combo highSelector = createRangeInclusionCombo(composite, !range.getUpper().isExclusive());
518 Composite buttonComposite = new Composite(shell, SWT.NONE);
519 GridDataFactory.fillDefaults().grab(true, false).align(SWT.TRAIL, SWT.FILL).applyTo(buttonComposite);
520 GridLayoutFactory.swtDefaults().numColumns(2).equalWidth(true).applyTo(buttonComposite);
522 Button ok = new Button(buttonComposite, SWT.NONE);
523 ok.setText(IDialogConstants.OK_LABEL);
524 GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).applyTo(ok);
525 Button cancel = new Button(buttonComposite, SWT.NONE);
526 cancel.setText(IDialogConstants.CANCEL_LABEL);
527 GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).applyTo(ok);
529 if (range.getLower().getValue() != null)
530 lowText.setText(range.getLower().getValue().toString());
531 if (range.getUpper().getValue() != null)
532 highText.setText(range.getUpper().getValue().toString());
534 shell.addListener(SWT.Deactivate, new org.eclipse.swt.widgets.Listener() {
536 public void handleEvent(Event event) {
541 ok.addSelectionListener(new SelectionAdapter() {
542 public void widgetSelected(SelectionEvent e) {
544 final Range newRange = parseRange(propertyInfo.numberType,
545 lowText.getText().trim(),
546 highText.getText().trim(),
547 lowSelector.getSelectionIndex() == 0 ? true : false,
548 highSelector.getSelectionIndex() == 0 ? true : false);
552 if (propertyInfo.immutable)
555 Simantics.getSession().async(new WriteRequest() {
557 public void perform(WriteGraph graph)
558 throws DatabaseException {
559 graph.markUndoPoint();
560 ComponentTypeCommands.setRange(graph, componentType, propertyInfo.resource, newRange == null ? null : newRange.toString());
563 } catch (RangeException ex) {
564 ErrorLogger.defaultLogError(ex);
568 cancel.addSelectionListener(new SelectionAdapter() {
569 public void widgetSelected(SelectionEvent e) {
575 Point size = shell.getSize();
577 Display display = table.getDisplay();
578 Rectangle clientArea = display.getClientArea();
579 Point bt = table.toDisplay(selectedItemBounds.x, selectedItemBounds.y);
580 Rectangle b = selectedItemBounds;
585 if ((b.x + b.width) > clientArea.width)
586 b.x -= b.x + b.width - clientArea.width;
587 if (b.height > clientArea.height)
588 b.height = clientArea.height;
589 if ((b.y + b.height) > clientArea.height)
590 b.y -= b.y + b.height - clientArea.height;
592 shell.setBounds(selectedItemBounds);
596 public void editMultilineText(Table table, TableEditor editor,
597 final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem,
598 Rectangle selectedItemBounds, int column, final StringWriter writer)
600 final Shell shell = new Shell(table.getShell(), SWT.ON_TOP);
601 GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(shell);
602 final StyledText text = new StyledText(shell, SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | (propertyInfo.immutable ? SWT.READ_ONLY : 0));
603 GridDataFactory.fillDefaults().grab(true, true).applyTo(text);
604 text.setText(selectedItem.getText(column));
605 org.eclipse.swt.widgets.Listener listener =
606 new org.eclipse.swt.widgets.Listener() {
608 public void handleEvent(Event e) {
609 final String newValue = text.getText();
611 if (e.type == SWT.Traverse) {
612 if (e.detail == SWT.TRAVERSE_ESCAPE) {
617 if (e.detail == SWT.TRAVERSE_ARROW_NEXT
618 || e.detail == SWT.TRAVERSE_ARROW_PREVIOUS
619 || e.detail == SWT.TRAVERSE_MNEMONIC)
621 if ((e.stateMask & SWT.CTRL) == 0)
628 if (propertyInfo.immutable)
631 if (writer != null) {
632 Simantics.getSession().async(new WriteRequest() {
634 public void perform(WriteGraph graph) throws DatabaseException {
635 writer.perform(graph, newValue);
642 String helpText = propertyInfo.immutable ? Messages.ComponentTypeViewerData_ESCToClose : Messages.ComponentTypeViewerData_CtrlEnterApplyChanges;
643 Label help = tk.createLabel(shell, helpText, SWT.BORDER | SWT.FLAT);
644 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(help);
645 help.setForeground( tk.getColors().createColor( "fg", tk.getColors().getSystemColor(SWT.COLOR_LIST_SELECTION) ) ); //$NON-NLS-1$
647 Display display = table.getDisplay();
648 Rectangle clientArea = display.getClientArea();
649 Point bt = table.toDisplay(selectedItemBounds.x, selectedItemBounds.y);
650 Rectangle b = selectedItemBounds;
654 if ((b.x + b.width) > clientArea.width)
655 b.x -= b.x + b.width - clientArea.width;
656 if (b.height > clientArea.height)
657 b.height = clientArea.height;
658 if ((b.y + b.height) > clientArea.height)
659 b.y -= b.y + b.height - clientArea.height;
661 shell.setBounds(selectedItemBounds);
667 text.addListener(SWT.Traverse, listener);
668 shell.addListener(SWT.Deactivate, listener);
671 private String validatePropertyName(ComponentTypeViewerPropertyInfo propertyInfo, String propertyName, Pattern namePattern) {
672 if (propertyName.equals(propertyInfo.name))
674 for (ComponentTypeViewerPropertyInfo info : properties) {
675 if (propertyName.equals(info.name))
676 return NLS.bind(Messages.ComponentTypeViewerData_PropertyNameInUse, propertyName);
678 for (NamedResource cp : connectionPoints) {
679 if (propertyName.equals(cp.getName()))
680 return NLS.bind(Messages.ComponentTypeViewerData_NameInUse, propertyName );
682 Matcher m = namePattern.matcher(propertyName);
684 return NLS.bind(Messages.ComponentTypeViewerData_ContainsInvalidCharacters, propertyName, namePattern.pattern());