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