]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ConfigurationPropertiesSection.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / componentTypeEditor / ConfigurationPropertiesSection.java
1 package org.simantics.modeling.ui.componentTypeEditor;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.Collection;\r
5 import java.util.Collections;\r
6 import java.util.HashMap;\r
7 import java.util.HashSet;\r
8 import java.util.List;\r
9 import java.util.Map;\r
10 import java.util.Set;\r
11 \r
12 import org.eclipse.jface.dialogs.IDialogSettings;\r
13 import org.eclipse.jface.layout.GridDataFactory;\r
14 import org.eclipse.jface.layout.GridLayoutFactory;\r
15 import org.eclipse.jface.layout.TableColumnLayout;\r
16 import org.eclipse.jface.resource.ImageDescriptor;\r
17 import org.eclipse.jface.viewers.ColumnWeightData;\r
18 import org.eclipse.jface.window.Window;\r
19 import org.eclipse.swt.SWT;\r
20 import org.eclipse.swt.custom.TableEditor;\r
21 import org.eclipse.swt.events.DisposeEvent;\r
22 import org.eclipse.swt.events.DisposeListener;\r
23 import org.eclipse.swt.events.MouseAdapter;\r
24 import org.eclipse.swt.events.MouseEvent;\r
25 import org.eclipse.swt.events.SelectionAdapter;\r
26 import org.eclipse.swt.events.SelectionEvent;\r
27 import org.eclipse.swt.graphics.Color;\r
28 import org.eclipse.swt.graphics.Rectangle;\r
29 import org.eclipse.swt.layout.FillLayout;\r
30 import org.eclipse.swt.widgets.Button;\r
31 import org.eclipse.swt.widgets.Composite;\r
32 import org.eclipse.swt.widgets.Control;\r
33 import org.eclipse.swt.widgets.Shell;\r
34 import org.eclipse.swt.widgets.Table;\r
35 import org.eclipse.swt.widgets.TableColumn;\r
36 import org.eclipse.swt.widgets.TableItem;\r
37 import org.eclipse.ui.PlatformUI;\r
38 import org.eclipse.ui.forms.widgets.Form;\r
39 import org.eclipse.ui.forms.widgets.FormToolkit;\r
40 import org.eclipse.ui.forms.widgets.Section;\r
41 import org.simantics.Logger;\r
42 import org.simantics.Simantics;\r
43 import org.simantics.databoard.Bindings;\r
44 import org.simantics.db.ReadGraph;\r
45 import org.simantics.db.Resource;\r
46 import org.simantics.db.WriteGraph;\r
47 import org.simantics.db.common.CommentMetadata;\r
48 import org.simantics.db.common.request.ObjectsWithType;\r
49 import org.simantics.db.common.request.PossibleIndexRoot;\r
50 import org.simantics.db.common.request.UniqueRead;\r
51 import org.simantics.db.common.request.WriteRequest;\r
52 import org.simantics.db.common.utils.NameUtils;\r
53 import org.simantics.db.exception.DatabaseException;\r
54 import org.simantics.db.layer0.adapter.CopyHandler2;\r
55 import org.simantics.db.layer0.adapter.Instances;\r
56 import org.simantics.db.layer0.util.Layer0Utils;\r
57 import org.simantics.db.layer0.variable.Variable;\r
58 import org.simantics.db.layer0.variable.Variables;\r
59 import org.simantics.layer0.Layer0;\r
60 import org.simantics.modeling.ui.Activator;\r
61 import org.simantics.modeling.ui.componentTypeEditor.LiftPropertiesDialog.LiftedProperty;\r
62 import org.simantics.modeling.userComponent.ComponentTypeCommands;\r
63 import org.simantics.selectionview.SelectionViewResources;\r
64 import org.simantics.structural.stubs.StructuralResource2;\r
65 import org.simantics.utils.datastructures.Pair;\r
66 \r
67 public class ConfigurationPropertiesSection implements ComponentTypeViewerSection {\r
68 \r
69     private static final String[] COLUMN_NAMES = \r
70             new String[] {"Name", "Type", "Default Value", "Unit", "Range", "Label", "Description"};\r
71     private static final int[] COLUMN_LENGTHS =\r
72             new int[] { 120, 100, 100, 50, 100, 100, 100 };\r
73     private static final int[] COLUMN_WEIGHTS =\r
74             new int[] { 0, 0, 0, 0, 0, 50, 100 };\r
75 \r
76     /**\r
77      * Configuration property table column indexes that are to be considered\r
78      * immutable when the property relation is immutable. Note that relation\r
79      * immutability does not make the asserted default value immutable.\r
80      */\r
81     private static final int[] IMMUTABLE_COLUMNS_WITH_IMMUTABLE_RELATION =\r
82         { 0, 1, 3, 4, 5, 6 };\r
83     \r
84     ComponentTypeViewerData data;\r
85     Table table;\r
86     TableColumn[] columns;\r
87     TableEditor editor;\r
88     Button newProperty;\r
89     Button removeProperty;\r
90     Button liftProperties;\r
91 \r
92     boolean hasTypes = false;\r
93     Button setTypes;\r
94     \r
95     Section section;\r
96     \r
97     public ConfigurationPropertiesSection(ComponentTypeViewerData data) {\r
98         this.data = data;\r
99         FormToolkit tk = data.tk;\r
100         Form form = data.form;\r
101         \r
102         section = tk.createSection(form.getBody(), Section.TITLE_BAR | Section.EXPANDED);\r
103         section.setLayout(new FillLayout());\r
104         section.setText("Configuration properties");\r
105 \r
106         Composite sectionBody = tk.createComposite(section);\r
107         GridLayoutFactory.fillDefaults().numColumns(2).applyTo(sectionBody);\r
108         section.setClient(sectionBody);\r
109 \r
110         Composite tableComposite = tk.createComposite(sectionBody);\r
111         GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(tableComposite);\r
112         TableColumnLayout tcl = new TableColumnLayout();\r
113         tableComposite.setLayout(tcl);\r
114 \r
115         table = tk.createTable(tableComposite, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);\r
116         table.setLinesVisible(true);\r
117         table.setHeaderVisible(true);\r
118 \r
119         columns = new TableColumn[COLUMN_NAMES.length];\r
120         for(int i=0;i<COLUMN_NAMES.length;++i) {\r
121             TableColumn column = new TableColumn(table, SWT.NONE);\r
122             columns[i] = column;\r
123             tcl.setColumnData(column, new ColumnWeightData(COLUMN_WEIGHTS[i], COLUMN_LENGTHS[i], true));\r
124             column.setText(COLUMN_NAMES[i]);\r
125         }\r
126 \r
127         // Table editor\r
128         editor = new TableEditor(table);\r
129         editor.grabHorizontal = true;\r
130         editor.grabVertical = true;\r
131         editor.horizontalAlignment = SWT.LEFT;\r
132         table.addMouseListener(new MouseAdapter() {\r
133             @Override\r
134             public void mouseDown(MouseEvent e) {\r
135                 // Clean up any previous editor control\r
136                 Control oldEditor = editor.getEditor();\r
137                 if (oldEditor != null) oldEditor.dispose();\r
138 \r
139                 if (data.readOnly)\r
140                     return;\r
141 \r
142                 // Relative position\r
143                 Rectangle tableBounds = table.getClientArea();\r
144                 int rx = e.x - tableBounds.x;\r
145                 int ry = e.y - tableBounds.y;\r
146 \r
147                 // Find cell\r
148                 TableItem selectedItem = null;\r
149                 int selectedColumn = -1;\r
150                 Rectangle selectedItemBounds = null;\r
151                 for(TableItem item : table.getItems()) {\r
152                     for(int column = 0;column < COLUMN_NAMES.length;++column) {\r
153                         Rectangle bounds = item.getBounds(column);\r
154                         if(bounds.contains(rx, ry)) {\r
155                             selectedItemBounds = bounds;\r
156                             selectedItem = item;\r
157                             selectedColumn = column;\r
158                             break;\r
159                         }\r
160                     }\r
161                 }\r
162                 if(selectedItem == null) {\r
163                     return;\r
164                 }\r
165 \r
166                 // Table editor\r
167                 final int column = selectedColumn; \r
168                 final ComponentTypeViewerPropertyInfo propertyInfo = (ComponentTypeViewerPropertyInfo)selectedItem.getData();\r
169                 final Resource resource = propertyInfo.resource;\r
170                 switch (column) {\r
171                 case 0:\r
172                     data.editName(table, editor, propertyInfo, selectedItem, column, ComponentTypeViewerData.PROPERTY_NAME_PATTERN);\r
173                     break;\r
174 \r
175                 case 1:\r
176                     data.editType(table, editor, propertyInfo, selectedItem, column, true);\r
177                     break;\r
178 \r
179                 case 2: {\r
180                     data.editValue(table, editor, propertyInfo, selectedItem, column, data.readOnly ? null : new StringWriter() {\r
181                         @Override\r
182                         public void perform(WriteGraph graph, String newValue) throws DatabaseException {\r
183                             graph.markUndoPoint();\r
184                             ComponentTypeCommands.setDefaultValue(graph, data.componentType, propertyInfo.resource, newValue);\r
185                         }\r
186                     }, null);\r
187                 } break;\r
188 \r
189                 case 3:\r
190                     data.editUnit(table, editor, propertyInfo, selectedItem, column);\r
191                     break;\r
192 \r
193                 case 4:\r
194                     data.editRange(table, editor, propertyInfo, selectedItem, selectedItemBounds, column);\r
195                     break;\r
196 \r
197                 case 5:\r
198                     data.editValue(table, editor, propertyInfo, selectedItem, column, propertyInfo.immutable ? null : new StringWriter() {\r
199                         @Override\r
200                         public void perform(WriteGraph graph, String newValue) throws DatabaseException {\r
201                             graph.markUndoPoint();\r
202                             String value = newValue.isEmpty() ? null : newValue;\r
203                             ComponentTypeCommands.setLabel(graph, resource, value);\r
204                         }\r
205                     }, null);\r
206                     break;\r
207 \r
208                 case 6:\r
209                     data.editMultilineText(table, editor, propertyInfo, selectedItem, selectedItemBounds, column, new StringWriter() {\r
210                         @Override\r
211                         public void perform(WriteGraph graph, String newValue) throws DatabaseException {\r
212                             graph.markUndoPoint();\r
213                             String value = newValue.isEmpty() ? null : newValue;\r
214                             ComponentTypeCommands.setDescription(graph, resource, value);\r
215                         }\r
216                     });\r
217                     break;\r
218                 }\r
219             }\r
220         });\r
221 \r
222         // Buttons\r
223 \r
224         Composite buttons = tk.createComposite(sectionBody);\r
225         GridDataFactory.fillDefaults().applyTo(buttons);\r
226         GridLayoutFactory.fillDefaults().applyTo(buttons);\r
227 \r
228         newProperty = tk.createButton(buttons, "New property", SWT.PUSH);\r
229         GridDataFactory.fillDefaults().applyTo(newProperty);\r
230         removeProperty = tk.createButton(buttons, "Remove property", SWT.PUSH);\r
231         GridDataFactory.fillDefaults().applyTo(removeProperty);\r
232 \r
233         liftProperties = tk.createButton(buttons, "Lift Properties", SWT.PUSH);\r
234         GridDataFactory.fillDefaults().applyTo(liftProperties);\r
235 \r
236         hasTypes = !getTypes().isEmpty();\r
237         \r
238         if(hasTypes) {\r
239             setTypes = tk.createButton(buttons, "Assign Types", SWT.PUSH);\r
240             GridDataFactory.fillDefaults().applyTo(setTypes);\r
241         }\r
242 \r
243         // Actions\r
244 \r
245         table.addSelectionListener(new SelectionAdapter() {\r
246             @Override\r
247             public void widgetSelected(SelectionEvent e) {\r
248                 TableItem[] sel = table.getSelection();\r
249                 for (TableItem item : sel) {\r
250                     ComponentTypeViewerPropertyInfo pi = (ComponentTypeViewerPropertyInfo) item.getData();\r
251                     if (pi.immutable) {\r
252                         removeProperty.setEnabled(false);\r
253                         return;\r
254                     }\r
255                 }\r
256                 removeProperty.setEnabled(true);\r
257             }\r
258         });\r
259 \r
260         newProperty.addSelectionListener(new SelectionAdapter() {\r
261             @Override\r
262             public void widgetSelected(SelectionEvent e) {\r
263                 if(editor.getEditor() != null)\r
264                     editor.getEditor().dispose();\r
265                 Simantics.getSession().async(new WriteRequest() {\r
266                     @Override\r
267                     public void perform(WriteGraph graph)\r
268                             throws DatabaseException {\r
269                         ComponentTypeCommands.createPropertyWithDefaults(graph, data.componentType);\r
270                     }\r
271                 });\r
272             }\r
273         });\r
274 \r
275         removeProperty.addSelectionListener(new SelectionAdapter() {\r
276             @Override\r
277             public void widgetSelected(SelectionEvent e) {\r
278                 if(editor.getEditor() != null)\r
279                     editor.getEditor().dispose();\r
280                 final List<Resource> propertiesToBeRemoved = \r
281                         new ArrayList<>();\r
282                 for(TableItem item : table.getSelection()) {\r
283                     ComponentTypeViewerPropertyInfo info = (ComponentTypeViewerPropertyInfo) item.getData();\r
284                     if (!info.immutable)\r
285                         propertiesToBeRemoved.add(info.resource);\r
286                 }\r
287                 System.out.println("remove " + propertiesToBeRemoved.size() + " resources");\r
288                 if(!propertiesToBeRemoved.isEmpty())\r
289                     Simantics.getSession().async(new WriteRequest() {\r
290                         @Override\r
291                         public void perform(WriteGraph graph)\r
292                                 throws DatabaseException {\r
293                             graph.markUndoPoint();\r
294                             for(Resource property : propertiesToBeRemoved)\r
295                                 ComponentTypeCommands.removeProperty(graph, data.componentType, property);\r
296                         }\r
297                     });\r
298             }\r
299         });\r
300         \r
301         liftProperties.addSelectionListener(new SelectionAdapter() {\r
302             @Override\r
303             public void widgetSelected(SelectionEvent e) {\r
304                 \r
305                 if(editor.getEditor() != null)\r
306                     editor.getEditor().dispose();\r
307 \r
308                 try {\r
309                 \r
310                     Map<LiftedProperty, Pair<String, ImageDescriptor>> map = Simantics.sync(new UniqueRead<Map<LiftedProperty,Pair<String,ImageDescriptor>>>() {\r
311     \r
312                         @Override\r
313                         public Map<LiftedProperty, Pair<String, ImageDescriptor>> perform(ReadGraph graph) throws DatabaseException {\r
314                             \r
315                             Map<LiftedProperty, Pair<String,ImageDescriptor>> map = new HashMap<>(); \r
316                             \r
317                             Layer0 L0 = Layer0.getInstance(graph);\r
318                             StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
319                             SelectionViewResources SEL = SelectionViewResources.getInstance(graph);\r
320     \r
321                             Resource composite = graph.getPossibleObject(data.componentType, STR.IsDefinedBy);\r
322                             if(composite == null) return map;\r
323 \r
324 \r
325                             Set<String> existing = new HashSet<>();\r
326                             for(Resource predicate : graph.getObjects(data.componentType, L0.DomainOf)) {\r
327                                 if(graph.isSubrelationOf(predicate, L0.HasProperty)) {\r
328                                     existing.add(NameUtils.getSafeName(graph, predicate));\r
329                                 }\r
330                             }\r
331                             \r
332                             for(Resource component : graph.syncRequest(new ObjectsWithType(composite, L0.ConsistsOf, STR.Component))) {\r
333     \r
334                                 Resource type = graph.getPossibleType(component, STR.Component);\r
335                                 if(type == null) continue;\r
336                                 \r
337                                 String componentName = NameUtils.getSafeName(graph, component);\r
338     \r
339                                 for(Resource predicate : graph.getPredicates(component)) {\r
340                                     if(graph.isSubrelationOf(predicate, L0.HasProperty)) {\r
341     \r
342                                         // Do not list properties shown under other properties\r
343                                         if(graph.hasStatement(predicate, SEL.IsShownUnder)) continue;\r
344                                         \r
345                                         // Do not list properties that are not visible in selection view\r
346                                         if(!graph.hasStatement(predicate, SEL.HasStandardPropertyInfo)) continue;\r
347                                         \r
348                                         // Some properties are explicitly marked as non-liftable\r
349                                         Boolean canBeLifted = graph.getPossibleRelatedValue(predicate, SEL.canBeLifted, Bindings.BOOLEAN);\r
350                                         if(canBeLifted != null && !canBeLifted) continue;\r
351                                         \r
352                                         String predicateName = NameUtils.getSafeName(graph, predicate);\r
353                                         if(existing.contains(predicateName)) continue;\r
354                                         \r
355                                         String name = componentName + " " + predicateName;\r
356                                         map.put(new LiftedProperty(component, type, predicate), new Pair<String, ImageDescriptor>(name, null));\r
357                                         \r
358                                     }\r
359                                 }\r
360                                 \r
361                             }\r
362                             \r
363                             return map;\r
364                             \r
365                         }\r
366     \r
367                     });\r
368                     \r
369                     Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
370                     LiftPropertiesDialog dialog = new LiftPropertiesDialog(shell, map, "Select properties to lift") {\r
371                         @Override\r
372                         protected IDialogSettings getBaseDialogSettings() {\r
373                             return Activator.getDefault().getDialogSettings();\r
374                         }\r
375                     };\r
376                     if (dialog.open() == Window.OK) {\r
377                         final Collection<LiftedProperty> _result = dialog.getResultT();\r
378                         final boolean mapProperties = dialog.getMapProperties();\r
379                         if (!_result.isEmpty()) {\r
380                             Simantics.getSession().async(new WriteRequest() {\r
381                                 public Resource findAssertion(ReadGraph graph, Resource sourceType, Resource predicate) throws DatabaseException {\r
382                                     Collection<Resource> ass = graph.getAssertedObjects(sourceType, predicate);\r
383                                     if(ass.size() == 1) return ass.iterator().next();\r
384                                     return null;\r
385                                 }\r
386                                 \r
387                                 public void processSubs(ReadGraph graph, Resource predicate, Resource component, Resource componentType, List<LiftedProperty> result, List<Resource> properties, List<Resource> assertions) throws DatabaseException {\r
388                                     SelectionViewResources SEL = SelectionViewResources.getInstance(graph);\r
389                                     for(Resource sub : graph.getObjects(predicate, SEL.UnderOf)) {\r
390                                         Resource ass = findAssertion(graph, componentType, sub);\r
391                                         if(ass == null) continue;\r
392                                         result.add(new LiftedProperty(component, componentType, sub));\r
393                                         properties.add(sub);\r
394                                         assertions.add(ass);\r
395                                         processSubs(graph, sub, component, componentType, result, properties, assertions);\r
396                                     }\r
397                                 }\r
398                                 \r
399                                 @Override\r
400                                 public void perform(WriteGraph graph) throws DatabaseException {\r
401                                     \r
402                                     Layer0 L0 = Layer0.getInstance(graph);\r
403                                     graph.markUndoPoint();\r
404                                     List<Resource> properties = new ArrayList<>();\r
405                                     List<Resource> assertions = new ArrayList<>();\r
406                                     \r
407                                     List<LiftedProperty> result = new ArrayList<>(); \r
408                                     for(LiftedProperty p : _result) {\r
409                                         Resource ass = findAssertion(graph, p.getComponentType(), p.getPredicate());\r
410                                         if(ass == null) continue;\r
411                                         result.add(p);\r
412                                         properties.add(p.getPredicate());\r
413                                         assertions.add(ass);\r
414                                         processSubs(graph, p.getPredicate(), p.getComponent(), p.getComponentType(), result, properties, assertions);\r
415                                     }\r
416                                     \r
417                                     CopyHandler2 ch = Layer0Utils.getPossibleCopyHandler(graph, properties);\r
418                                     Collection<Resource> copies = Layer0Utils.copyTo(graph, data.componentType, null, ch, null);\r
419                                     int index = 0;\r
420                                     for(Resource copy : copies) {\r
421                                         Resource ass = assertions.get(index);\r
422                                         LiftedProperty p = result.get(index);\r
423                                         Collection<Resource> copyAss = Layer0Utils.copyTo(graph, null, ass);\r
424                                         if(copyAss.size() == 1) {\r
425                                             graph.claim(data.componentType, L0.DomainOf, copy);\r
426                                             Layer0Utils.assert_(graph, data.componentType, copy, copyAss.iterator().next());\r
427                                             CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
428                                             graph.addMetadata(cm.add("Lifted property " + NameUtils.getSafeName(graph, copy) + " into "+ NameUtils.getSafeName(graph, data.componentType)));\r
429                                         }\r
430                                         if(mapProperties) {\r
431                                             Variable v = Variables.getVariable(graph, p.getComponent());\r
432                                             Variable property = v.getProperty(graph, p.getPredicate());\r
433                                             Variable displayValue = property.getProperty(graph, Variables.DISPLAY_VALUE);\r
434                                             displayValue.setValue(graph, "=" + NameUtils.getSafeName(graph, p.getPredicate()), Bindings.STRING);\r
435                                         }\r
436                                         index++;\r
437                                     }\r
438                                     \r
439                                 }\r
440                             });\r
441                         }\r
442                     }\r
443 \r
444                 } catch (DatabaseException e1) {\r
445                     \r
446                     Logger.defaultLogError(e1);\r
447                     return;\r
448                     \r
449                 }\r
450                 \r
451             }\r
452         });\r
453 \r
454         if(hasTypes) {\r
455             \r
456             setTypes.addSelectionListener(new SelectionAdapter() {\r
457                 @Override\r
458                 public void widgetSelected(SelectionEvent e) {\r
459                     if(editor.getEditor() != null)\r
460                         editor.getEditor().dispose();\r
461                     final List<Resource> propertiesToSet = \r
462                             new ArrayList<>();\r
463                     for(TableItem item : table.getSelection())\r
464                         propertiesToSet.add(((ComponentTypeViewerPropertyInfo)item.getData()).resource);\r
465                     \r
466                     if(propertiesToSet.size() != 1) return;\r
467 \r
468                     Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
469                     SetTypesDialog page = new SetTypesDialog(shell, getTypes(), "Select user types for property");\r
470                     if (page.open() == Window.OK) {\r
471                         final Object[] result = page.getResult();\r
472                         if (result != null && result.length > 0) {\r
473                             Simantics.getSession().async(new WriteRequest() {\r
474                                 @Override\r
475                                 public void perform(WriteGraph graph)\r
476                                         throws DatabaseException {\r
477                                     for(Object type : result) {\r
478                                         Layer0 L0 = Layer0.getInstance(graph);\r
479                                         graph.claim(propertiesToSet.get(0), L0.InstanceOf, null, (Resource)type);\r
480                                     }\r
481                                 }\r
482                             });\r
483                         }\r
484                     }\r
485                     \r
486                 }\r
487             });\r
488             \r
489         }\r
490 \r
491         table.addDisposeListener(new DisposeListener() {\r
492             @Override\r
493             public void widgetDisposed(DisposeEvent e) {\r
494                 tk.dispose();\r
495             }\r
496         });\r
497     }\r
498 \r
499     public void update(ComponentTypePropertiesResult result) {\r
500         if (table.isDisposed())\r
501             return;\r
502         \r
503         // Save old selection\r
504         Set<ComponentTypeViewerPropertyInfo> selected = new HashSet<>();\r
505         List<TableItem> selectedItems = new ArrayList<>(selected.size());\r
506         for (int i : table.getSelectionIndices()) {\r
507             TableItem item = table.getItem(i);\r
508             selected.add((ComponentTypeViewerPropertyInfo) item.getData());\r
509         }\r
510 \r
511         int topIndex = table.getTopIndex();\r
512 \r
513         table.removeAll();\r
514 \r
515         if(editor.getEditor() != null)\r
516             editor.getEditor().dispose();\r
517 \r
518         for(ComponentTypeViewerPropertyInfo info : result.getProperties()) {\r
519             boolean immutable = result.isImmutable() || info.immutable;\r
520             Color fg = immutable ? table.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY) : null;\r
521             if(info.sectionSpecificData != null)\r
522                 continue;\r
523 \r
524             TableItem item = new TableItem(table, SWT.NONE);\r
525 \r
526             item.setText(0, info.name);\r
527             item.setText(1, info.type);\r
528             item.setText(2, info.defaultValue);\r
529             item.setText(3, unitStr(info));\r
530             item.setText(4, rangeStr(info));\r
531             item.setText(5, info.label);\r
532             item.setText(6, info.description);\r
533 \r
534             for (int columnIndex : IMMUTABLE_COLUMNS_WITH_IMMUTABLE_RELATION)\r
535                 item.setForeground(columnIndex, fg);\r
536 \r
537             item.setData(info);\r
538 \r
539             if (selected.contains(info))\r
540                 selectedItems.add(item);\r
541         }\r
542 \r
543         // Restore old selection\r
544         table.setTopIndex(topIndex);\r
545         table.setSelection(selectedItems.toArray(new TableItem[selectedItems.size()]));\r
546         table.redraw();\r
547     }\r
548     \r
549     private Map<Resource, Pair<String, ImageDescriptor>> getTypes() {\r
550         try {\r
551             return Simantics.getSession().syncRequest(new UniqueRead<Map<Resource, Pair<String, ImageDescriptor>>>() {\r
552                 @Override\r
553                 public Map<Resource, Pair<String, ImageDescriptor>> perform(ReadGraph graph)\r
554                         throws DatabaseException {\r
555                     StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
556                     Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(data.componentType));\r
557                     Instances query = graph.adapt(STR.UserDefinedProperty, Instances.class);\r
558                     Collection<Resource> types = query.find(graph, indexRoot);\r
559                     Map<Resource, Pair<String, ImageDescriptor>> result = new HashMap<>();\r
560                     for(Resource type : types) {\r
561                         String name = NameUtils.getSafeLabel(graph, type);\r
562                         result.put(type, new Pair<String, ImageDescriptor>(name, null));\r
563                     }\r
564                     return result;\r
565                 }\r
566             });\r
567         } catch (DatabaseException e) {\r
568             Logger.defaultLogError(e);\r
569             return Collections.emptyMap();\r
570         }\r
571     }\r
572 \r
573     private String unitStr(ComponentTypeViewerPropertyInfo info) {\r
574         String unit = info.numberType == null ? null : info.numberType.getUnit();\r
575         if (unit == null)\r
576             unit = info.unit;\r
577         return unit != null ? unit : "";\r
578     }\r
579 \r
580     private String rangeStr(ComponentTypeViewerPropertyInfo info) {\r
581         String range = info.numberType == null ? null : info.numberType.getRangeStr();\r
582         return range != null ? range : "";\r
583     }\r
584     \r
585     @Override\r
586     public void setReadOnly(boolean readOnly) {\r
587         boolean e = !readOnly;\r
588         newProperty.setEnabled(e);\r
589         removeProperty.setEnabled(e);\r
590         liftProperties.setEnabled(e);\r
591     }\r
592     \r
593     @Override\r
594     public Section getSection() {\r
595         return section;\r
596     }\r
597 \r
598     @Override\r
599     public double getPriority() {\r
600         return 0;\r
601     }\r
602 \r
603     @Override\r
604     public Object getSectionSpecificData(ReadGraph graph,\r
605             ComponentTypeViewerPropertyInfo info) throws DatabaseException {\r
606         return null;\r
607     }\r
608 \r
609     @Override\r
610     public double getDataPriority() {\r
611         return 0.0;\r
612     }\r
613 }\r