]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ComponentTypeViewerData.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / componentTypeEditor / ComponentTypeViewerData.java
1 package org.simantics.modeling.ui.componentTypeEditor;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.Collections;\r
5 import java.util.List;\r
6 import java.util.regex.Matcher;\r
7 import java.util.regex.Pattern;\r
8 \r
9 import org.eclipse.jface.dialogs.IMessageProvider;\r
10 import org.eclipse.jface.layout.GridDataFactory;\r
11 import org.eclipse.jface.layout.GridLayoutFactory;\r
12 import org.eclipse.swt.SWT;\r
13 import org.eclipse.swt.custom.StyledText;\r
14 import org.eclipse.swt.custom.TableEditor;\r
15 import org.eclipse.swt.events.SelectionAdapter;\r
16 import org.eclipse.swt.events.SelectionEvent;\r
17 import org.eclipse.swt.graphics.Point;\r
18 import org.eclipse.swt.graphics.Rectangle;\r
19 import org.eclipse.swt.widgets.Button;\r
20 import org.eclipse.swt.widgets.Combo;\r
21 import org.eclipse.swt.widgets.Composite;\r
22 import org.eclipse.swt.widgets.Display;\r
23 import org.eclipse.swt.widgets.Event;\r
24 import org.eclipse.swt.widgets.Label;\r
25 import org.eclipse.swt.widgets.Shell;\r
26 import org.eclipse.swt.widgets.Table;\r
27 import org.eclipse.swt.widgets.TableItem;\r
28 import org.eclipse.swt.widgets.Text;\r
29 import org.eclipse.ui.forms.widgets.Form;\r
30 import org.eclipse.ui.forms.widgets.FormToolkit;\r
31 import org.simantics.Simantics;\r
32 import org.simantics.databoard.type.NumberType;\r
33 import org.simantics.databoard.units.internal.library.UnitLibrary;\r
34 import org.simantics.databoard.util.Limit;\r
35 import org.simantics.databoard.util.Range;\r
36 import org.simantics.databoard.util.RangeException;\r
37 import org.simantics.db.RequestProcessor;\r
38 import org.simantics.db.Resource;\r
39 import org.simantics.db.WriteGraph;\r
40 import org.simantics.db.common.NamedResource;\r
41 import org.simantics.db.common.request.WriteRequest;\r
42 import org.simantics.db.exception.DatabaseException;\r
43 import org.simantics.layer0.Layer0;\r
44 import org.simantics.modeling.userComponent.ComponentTypeCommands;\r
45 import org.simantics.scl.runtime.function.Function4;\r
46 import org.simantics.utils.ui.ErrorLogger;\r
47 \r
48 public class ComponentTypeViewerData {\r
49     /**\r
50      * Used to validate property names.\r
51      */\r
52     public static final Pattern PROPERTY_NAME_PATTERN =\r
53             Pattern.compile("([a-z]|_[0-9a-zA-Z_])[0-9a-zA-Z_]*");\r
54 \r
55     public static final String[] PROPERTY_TYPE_SUGGESTIONS = new String[] {\r
56         "Double",\r
57         "Integer",\r
58         "Float",\r
59         "String",\r
60         "Boolean",\r
61         "Long",\r
62         "[Double]",\r
63         "[Integer]",\r
64         "[Float]",\r
65         "[String]",\r
66         "[Boolean]",\r
67         "[Long]",\r
68         "Vector Double",\r
69         "Vector Integer",\r
70         "Vector Float",\r
71         "Vector String",\r
72         "Vector Boolean",\r
73         "Vector Long"        \r
74     };\r
75     \r
76     public Resource componentType;\r
77     public FormToolkit tk;\r
78     public Form form;\r
79     public UnitLibrary unitLibrary = UnitLibrary.createDefault();\r
80     public boolean readOnly;\r
81     public NamedResource[] connectionPoints;\r
82     public ComponentTypeViewerPropertyInfo[] properties;\r
83 \r
84     public ComponentTypeViewerData(FormToolkit tk, Resource componentType, Form form) {\r
85         this.tk = tk;\r
86         this.componentType = componentType;\r
87         this.form = form;\r
88     }\r
89     \r
90     public void editName(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column,\r
91             Pattern namePattern) {\r
92         int extraStyle = propertyInfo.immutable ? SWT.READ_ONLY : 0;\r
93         final Text text = new Text(table, SWT.NONE | extraStyle);\r
94         org.eclipse.swt.widgets.Listener listener = \r
95                 new org.eclipse.swt.widgets.Listener() {\r
96             @Override\r
97             public void handleEvent(Event e) {\r
98                 if (e.type == SWT.Dispose) {\r
99                     form.setMessage(null);\r
100                     return;\r
101                 }\r
102 \r
103                 if (e.type == SWT.Modify) {\r
104                     // validate current name\r
105                     String error = validatePropertyName(propertyInfo, text.getText(), namePattern);\r
106                     if (error != null) {\r
107                         text.setBackground(text.getDisplay().getSystemColor(SWT.COLOR_RED));\r
108                         form.setMessage(error, IMessageProvider.ERROR);\r
109                     } else {\r
110                         text.setBackground(null);\r
111                         form.setMessage(null);\r
112                     }\r
113                     return;\r
114                 }\r
115 \r
116                 if (e.type == SWT.Traverse) {\r
117                     if (e.detail == SWT.TRAVERSE_ESCAPE) {\r
118                         text.dispose();\r
119                         e.doit = false;\r
120                         return;\r
121                     }\r
122                     if (e.detail == SWT.TRAVERSE_ARROW_NEXT || e.detail == SWT.TRAVERSE_ARROW_PREVIOUS || e.detail == SWT.TRAVERSE_MNEMONIC)\r
123                         return;\r
124                     e.doit = false;\r
125                 }\r
126                 final String newValue = text.getText();\r
127                 text.dispose();\r
128 \r
129                 String error = validatePropertyName(propertyInfo, newValue, namePattern);\r
130                 if (error != null)\r
131                     return;\r
132 \r
133                 if (propertyInfo.immutable)\r
134                     return;\r
135 \r
136                 Simantics.getSession().async(new WriteRequest() {\r
137                     @Override\r
138                     public void perform(WriteGraph graph)\r
139                             throws DatabaseException {\r
140                         graph.markUndoPoint();\r
141                         Layer0 L0 = Layer0.getInstance(graph);\r
142                         String prevName = graph.getPossibleRelatedValue2(propertyInfo.resource, L0.HasName);\r
143                         String oldCamelCasedLabel = prevName != null ? ComponentTypeCommands.camelCaseNameToLabel(prevName) : "";\r
144                         String oldLabel = graph.getPossibleRelatedValue(propertyInfo.resource, L0.HasLabel);\r
145                         boolean setLabel = oldLabel == null\r
146                                 || oldLabel.isEmpty()\r
147                                 || oldCamelCasedLabel.isEmpty()\r
148                                 || oldCamelCasedLabel.equals(oldLabel);\r
149 \r
150                         ComponentTypeCommands.rename(graph, propertyInfo.resource, newValue);\r
151                         if (setLabel)\r
152                             ComponentTypeCommands.setLabel(graph, propertyInfo.resource, ComponentTypeCommands.camelCaseNameToLabel(newValue));\r
153                     }\r
154                 });\r
155             }\r
156         };\r
157         text.addListener(SWT.Modify, listener);\r
158         text.addListener(SWT.Deactivate, listener);\r
159         text.addListener(SWT.Traverse, listener);\r
160         text.addListener(SWT.Dispose, listener);\r
161 \r
162         text.setText(selectedItem.getText(column));\r
163         text.selectAll();\r
164         text.setFocus();\r
165 \r
166         editor.setEditor(text, selectedItem, column);\r
167     }\r
168 \r
169     public void editType(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column, final boolean convertDefaultValue) {\r
170         int extraStyle = propertyInfo.immutable ? SWT.READ_ONLY : 0;\r
171         final Combo combo = new Combo(table, SWT.NONE | extraStyle);\r
172         combo.setText(selectedItem.getText(column));\r
173         for(String suggestion : PROPERTY_TYPE_SUGGESTIONS)\r
174             combo.add(suggestion);\r
175         org.eclipse.swt.widgets.Listener listener = \r
176                 new org.eclipse.swt.widgets.Listener() {\r
177             @Override\r
178             public void handleEvent(Event e) {\r
179                 if(e.type == SWT.Traverse) {\r
180                     if (e.detail == SWT.TRAVERSE_ESCAPE) {\r
181                         combo.dispose();\r
182                         e.doit = false;\r
183                         return;\r
184                     }\r
185                     if (e.detail == SWT.TRAVERSE_ARROW_NEXT\r
186                             || e.detail == SWT.TRAVERSE_ARROW_PREVIOUS\r
187                             || e.detail == SWT.TRAVERSE_MNEMONIC)\r
188                         return;\r
189                 }\r
190                 final String newValue = combo.getText();\r
191                 if (e.type == SWT.Traverse) {\r
192                     e.doit = false;\r
193                 }\r
194                 combo.dispose();\r
195 \r
196                 if (propertyInfo.immutable)\r
197                     return;\r
198 \r
199                 Simantics.getSession().async(new WriteRequest() {\r
200                     @Override\r
201                     public void perform(WriteGraph graph)\r
202                             throws DatabaseException {\r
203                         graph.markUndoPoint();\r
204                         ComponentTypeCommands.editType(graph, componentType, propertyInfo.resource, convertDefaultValue, newValue);\r
205                     }\r
206                 });\r
207             }\r
208         };\r
209         combo.setFocus();\r
210         editor.setEditor(combo, selectedItem, column);\r
211         combo.addListener(SWT.FocusOut, listener);\r
212         combo.addListener(SWT.Traverse, listener);\r
213     }\r
214 \r
215     protected void editUnit(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, int column) {\r
216         // Disallow unit editing for non-numeric configuration properties\r
217         if (propertyInfo.numberType == null && propertyInfo.sectionSpecificData == null)\r
218             return;\r
219 \r
220         int extraStyle = propertyInfo.immutable ? SWT.READ_ONLY : 0;\r
221         final Combo combo = new Combo(table, SWT.NONE | extraStyle);\r
222         String initialValue = selectedItem.getText(column);\r
223         List<String> units = new ArrayList<>( unitLibrary.getUnits() );\r
224         Collections.sort(units, String.CASE_INSENSITIVE_ORDER);\r
225         int i = -1;\r
226         int selected = -1;\r
227         for (String unit : units) {\r
228             combo.add(unit);\r
229             if (unit.equals(initialValue))\r
230                 combo.select(i);\r
231         }\r
232         if (selected == -1)\r
233             combo.setText(initialValue);\r
234 \r
235         org.eclipse.swt.widgets.Listener listener = \r
236                 new org.eclipse.swt.widgets.Listener() {\r
237             @Override\r
238             public void handleEvent(Event e) {\r
239                 if(e.type == SWT.Traverse) {\r
240                     if (e.detail == SWT.TRAVERSE_ESCAPE) {\r
241                         combo.dispose();\r
242                         e.doit = false;\r
243                         return;\r
244                     }\r
245                     if (e.detail == SWT.TRAVERSE_ARROW_NEXT\r
246                             || e.detail == SWT.TRAVERSE_ARROW_PREVIOUS\r
247                             || e.detail == SWT.TRAVERSE_MNEMONIC)\r
248                         return;\r
249                 }\r
250                 final String newValue = combo.getText();\r
251                 if(e.type == SWT.Traverse) {\r
252                     e.doit = false;\r
253                 }\r
254                 combo.dispose();\r
255 \r
256                 if (propertyInfo.immutable)\r
257                     return;\r
258 \r
259                 Simantics.getSession().async(new WriteRequest() {\r
260                     @Override\r
261                     public void perform(WriteGraph graph)\r
262                             throws DatabaseException {\r
263                         graph.markUndoPoint();\r
264                         ComponentTypeCommands.setUnit(graph, componentType, propertyInfo.resource, newValue);\r
265                     }\r
266                 });\r
267             }\r
268         };\r
269         combo.setFocus();\r
270         editor.setEditor(combo, selectedItem, column);\r
271         combo.addListener(SWT.Deactivate, listener);\r
272         combo.addListener(SWT.Traverse, listener);\r
273     }\r
274 \r
275     public void editValue(Table table, TableEditor editor,\r
276             final ComponentTypeViewerPropertyInfo propertyInfo,\r
277             TableItem selectedItem, int column,\r
278             final StringWriter writer,\r
279             final Function4<RequestProcessor, Resource, Resource, String, String> validator)\r
280     {\r
281         int extraStyle = writer == null ? SWT.READ_ONLY : 0;\r
282         final Text text = new Text(table, SWT.NONE | extraStyle);\r
283         text.setText(selectedItem.getText(column));\r
284         org.eclipse.swt.widgets.Listener listener = \r
285                 new org.eclipse.swt.widgets.Listener() {\r
286             @Override\r
287             public void handleEvent(Event e) {\r
288                 if(e.type == SWT.Traverse) {\r
289                     if (e.detail == SWT.TRAVERSE_ESCAPE) {\r
290                         text.dispose();\r
291                         e.doit = false;\r
292                         return;\r
293                     }\r
294                     if (e.detail == SWT.TRAVERSE_ARROW_NEXT\r
295                             || e.detail == SWT.TRAVERSE_ARROW_PREVIOUS\r
296                             || e.detail == SWT.TRAVERSE_MNEMONIC)\r
297                         return;\r
298                 }\r
299                 final String newValue = text.getText();\r
300                 if(e.type == SWT.Traverse) {\r
301                     e.doit = false;\r
302                 }\r
303                 text.dispose();\r
304 \r
305                 if (writer != null) {\r
306                     Simantics.getSession().async(new WriteRequest() {\r
307                         @Override\r
308                         public void perform(WriteGraph graph) throws DatabaseException {\r
309                             writer.perform(graph, newValue);\r
310                         }\r
311                     });\r
312                 }\r
313             }\r
314         };\r
315         text.selectAll();\r
316         text.setFocus();\r
317         editor.setEditor(text, selectedItem, column);\r
318         text.addListener(SWT.FocusOut, listener);\r
319         text.addListener(SWT.Traverse, listener);\r
320 \r
321         if (validator != null) {\r
322             org.eclipse.swt.widgets.Listener validationListener = new org.eclipse.swt.widgets.Listener() {\r
323                 @Override\r
324                 public void handleEvent(Event e) {\r
325                     final String newValue = text.getText();\r
326                     String error = validator.apply(Simantics.getSession(), componentType, propertyInfo.resource, newValue);\r
327                     if (error != null) {\r
328                         text.setBackground(text.getDisplay().getSystemColor(SWT.COLOR_RED));\r
329                         text.setToolTipText(error);\r
330                         return;\r
331                     } else {\r
332                         text.setBackground(null);\r
333                         text.setToolTipText(null);\r
334                     }\r
335                 }\r
336             };\r
337             text.addListener(SWT.Modify, validationListener);\r
338         }\r
339     }\r
340 \r
341     private Range parseRange(NumberType numberType, String minStr, String maxStr, boolean lowInclusive, boolean highInclusive) throws RangeException {\r
342         try {\r
343             String rangeStr = (lowInclusive ? "[" : "(")  + minStr + ".." + maxStr + (highInclusive ? "]" : ")");\r
344             return Range.valueOf(rangeStr);\r
345         } catch (IllegalArgumentException e) {\r
346             // Limits are invalid\r
347             throw new RangeException(e.getMessage(), e);\r
348         }\r
349     }\r
350     \r
351     private static Combo createRangeInclusionCombo(Composite parent, boolean inclusive) {\r
352         Combo rng = new Combo(parent, SWT.READ_ONLY);\r
353         rng.add("Inclusive");\r
354         rng.add("Exclusive");\r
355         rng.select(inclusive ? 0 : 1);\r
356         return rng;\r
357     }\r
358     \r
359     protected void editRange(Table table, TableEditor editor, final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem, Rectangle selectedItemBounds, int column) {\r
360         // Disallow range editing when the property is not numeric\r
361         if (propertyInfo.numberType == null)\r
362             return;\r
363 \r
364         int extraTextStyle = propertyInfo.immutable ? SWT.READ_ONLY : 0;\r
365 \r
366         // Parse initial range value\r
367         Range range = null;\r
368         String rangeStr = selectedItem.getText(column);\r
369         try {\r
370             range = Range.valueOf(rangeStr);\r
371         } catch (RangeException ex) {\r
372             range = new Range(Limit.nolimit(), Limit.nolimit());\r
373         }\r
374 \r
375         final Shell shell = new Shell(table.getShell(), SWT.ON_TOP);\r
376         GridLayoutFactory.fillDefaults().applyTo(shell);\r
377 \r
378         Composite composite = new Composite(shell, SWT.NONE);\r
379         GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
380         GridLayoutFactory.swtDefaults().numColumns(3).applyTo(composite);\r
381 \r
382         Label low = new Label(composite, SWT.NONE);\r
383         low.setText("Minimum Value:");\r
384         final Text lowText = new Text(composite, SWT.BORDER | extraTextStyle);\r
385         GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).applyTo(lowText);\r
386         final Combo lowSelector = createRangeInclusionCombo(composite, !range.getLower().isExclusive());\r
387         Label high = new Label(composite, SWT.NONE);\r
388         high.setText("Maximum Value:");\r
389         final Text highText = new Text(composite, SWT.BORDER | extraTextStyle);\r
390         GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).applyTo(highText);\r
391         final Combo highSelector = createRangeInclusionCombo(composite, !range.getUpper().isExclusive());\r
392 \r
393         Composite buttonComposite = new Composite(shell, SWT.NONE);\r
394         GridDataFactory.fillDefaults().grab(true, false).align(SWT.TRAIL, SWT.FILL).applyTo(buttonComposite);\r
395         GridLayoutFactory.swtDefaults().numColumns(2).equalWidth(true).applyTo(buttonComposite);\r
396 \r
397         Button ok = new Button(buttonComposite, SWT.NONE);\r
398         ok.setText("&OK");\r
399         GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).applyTo(ok);\r
400         Button cancel = new Button(buttonComposite, SWT.NONE);\r
401         cancel.setText("&Cancel");\r
402         GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).applyTo(ok);\r
403 \r
404         if (range.getLower().getValue() != null)\r
405             lowText.setText(range.getLower().getValue().toString());\r
406         if (range.getUpper().getValue() != null)\r
407             highText.setText(range.getUpper().getValue().toString());\r
408 \r
409         shell.addListener(SWT.Deactivate, new org.eclipse.swt.widgets.Listener() {\r
410             @Override\r
411             public void handleEvent(Event event) {\r
412                 shell.dispose();\r
413             }\r
414         });\r
415 \r
416         ok.addSelectionListener(new SelectionAdapter() {\r
417             public void widgetSelected(SelectionEvent e) {\r
418                 try {\r
419                     final Range newRange = parseRange(propertyInfo.numberType,\r
420                             lowText.getText().trim(),\r
421                             highText.getText().trim(),\r
422                             lowSelector.getSelectionIndex() == 0 ? true : false,\r
423                             highSelector.getSelectionIndex() == 0 ? true : false);\r
424 \r
425                     shell.dispose();\r
426 \r
427                     if (propertyInfo.immutable)\r
428                         return;\r
429 \r
430                     Simantics.getSession().async(new WriteRequest() {\r
431                         @Override\r
432                         public void perform(WriteGraph graph)\r
433                                 throws DatabaseException {\r
434                             graph.markUndoPoint();\r
435                             ComponentTypeCommands.setRange(graph, componentType, propertyInfo.resource, newRange == null ? null : newRange.toString());\r
436                         }\r
437                     });\r
438                 } catch (RangeException ex) {\r
439                     ErrorLogger.defaultLogError(ex);\r
440                 }\r
441             }\r
442         });\r
443         cancel.addSelectionListener(new SelectionAdapter() {\r
444             public void widgetSelected(SelectionEvent e) {\r
445                 shell.dispose();\r
446             }\r
447         });\r
448 \r
449         shell.pack();\r
450         Point size = shell.getSize();\r
451 \r
452         Display display = table.getDisplay();\r
453         Rectangle clientArea = display.getClientArea();\r
454         Point bt = table.toDisplay(selectedItemBounds.x, selectedItemBounds.y);\r
455         Rectangle b = selectedItemBounds;\r
456         b.x = bt.x;\r
457         b.y = bt.y;\r
458         b.width = size.x;\r
459         b.height = size.y;\r
460         if ((b.x + b.width) > clientArea.width)\r
461             b.x -= b.x + b.width - clientArea.width;\r
462         if (b.height > clientArea.height)\r
463             b.height = clientArea.height;\r
464         if ((b.y + b.height) > clientArea.height)\r
465             b.y -= b.y + b.height - clientArea.height;\r
466 \r
467         shell.setBounds(selectedItemBounds);\r
468         shell.open();\r
469     }\r
470 \r
471     protected void editMultilineText(Table table, TableEditor editor,\r
472             final ComponentTypeViewerPropertyInfo propertyInfo, TableItem selectedItem,\r
473             Rectangle selectedItemBounds, int column, final StringWriter writer)\r
474     {\r
475         final Shell shell = new Shell(table.getShell(), SWT.ON_TOP);\r
476         GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(shell);\r
477         final StyledText text = new StyledText(shell, SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | (propertyInfo.immutable ? SWT.READ_ONLY : 0));\r
478         GridDataFactory.fillDefaults().grab(true, true).applyTo(text);\r
479         text.setText(selectedItem.getText(column));\r
480         org.eclipse.swt.widgets.Listener listener = \r
481                 new org.eclipse.swt.widgets.Listener() {\r
482             @Override\r
483             public void handleEvent(Event e) {\r
484                 final String newValue = text.getText();\r
485 \r
486                 if (e.type == SWT.Traverse) {\r
487                     if (e.detail == SWT.TRAVERSE_ESCAPE) {\r
488                         shell.dispose();\r
489                         e.doit = false;\r
490                         return;\r
491                     }\r
492                     if (e.detail == SWT.TRAVERSE_ARROW_NEXT\r
493                             || e.detail == SWT.TRAVERSE_ARROW_PREVIOUS\r
494                             || e.detail == SWT.TRAVERSE_MNEMONIC)\r
495                         return;\r
496                     if ((e.stateMask & SWT.CTRL) == 0)\r
497                         return;\r
498                     e.doit = false;\r
499                 }\r
500 \r
501                 shell.dispose();\r
502 \r
503                 if (propertyInfo.immutable)\r
504                     return;\r
505 \r
506                 if (writer != null) {\r
507                     Simantics.getSession().async(new WriteRequest() {\r
508                         @Override\r
509                         public void perform(WriteGraph graph) throws DatabaseException {\r
510                             writer.perform(graph, newValue);\r
511                         }\r
512                     });\r
513                 }\r
514             }\r
515         };\r
516 \r
517         String helpText = propertyInfo.immutable ? "ESC to close." : "Ctrl+Enter to apply changes, ESC to cancel.";\r
518         Label help = tk.createLabel(shell, helpText, SWT.BORDER | SWT.FLAT);\r
519         GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(help);\r
520         help.setForeground( tk.getColors().createColor( "fg", tk.getColors().getSystemColor(SWT.COLOR_LIST_SELECTION) ) );\r
521 \r
522         Display display = table.getDisplay();\r
523         Rectangle clientArea = display.getClientArea();\r
524         Point bt = table.toDisplay(selectedItemBounds.x, selectedItemBounds.y);\r
525         Rectangle b = selectedItemBounds;\r
526         b.x = bt.x;\r
527         b.y = bt.y;\r
528         b.height = 200;\r
529         if ((b.x + b.width) > clientArea.width)\r
530             b.x -= b.x + b.width - clientArea.width;\r
531         if (b.height > clientArea.height)\r
532             b.height = clientArea.height;\r
533         if ((b.y + b.height) > clientArea.height)\r
534             b.y -= b.y + b.height - clientArea.height;\r
535 \r
536         shell.setBounds(selectedItemBounds);\r
537         shell.open();\r
538 \r
539         text.selectAll();\r
540         text.setFocus();\r
541 \r
542         text.addListener(SWT.Traverse, listener);\r
543         shell.addListener(SWT.Deactivate, listener);\r
544     }\r
545 \r
546     private String validatePropertyName(ComponentTypeViewerPropertyInfo propertyInfo, String propertyName, Pattern namePattern) {\r
547         if (propertyName.equals(propertyInfo.name))\r
548             return null;\r
549         for (ComponentTypeViewerPropertyInfo info : properties) {\r
550             if (propertyName.equals(info.name))\r
551                 return "Property name '" + propertyName + "' is already in use.";\r
552         }\r
553         for (NamedResource cp : connectionPoints) {\r
554             if (propertyName.equals(cp.getName()))\r
555                 return "Name '" + propertyName + "' is already used for a terminal.";\r
556         }\r
557         Matcher m = namePattern.matcher(propertyName);\r
558         if (!m.matches())\r
559             return "Property name '" + propertyName + "' contains invalid characters, does not match pattern "\r
560                     + namePattern.pattern() + ".";\r
561         return null;\r
562     }\r
563 \r
564 }\r