1 package org.simantics.modeling.ui.componentTypeEditor;
3 import java.util.ArrayList;
4 import java.util.HashSet;
8 import org.eclipse.jface.layout.GridDataFactory;
9 import org.eclipse.jface.layout.GridLayoutFactory;
10 import org.eclipse.jface.layout.TableColumnLayout;
11 import org.eclipse.jface.viewers.ColumnWeightData;
12 import org.eclipse.swt.SWT;
13 import org.eclipse.swt.custom.TableEditor;
14 import org.eclipse.swt.events.MouseAdapter;
15 import org.eclipse.swt.events.MouseEvent;
16 import org.eclipse.swt.events.SelectionAdapter;
17 import org.eclipse.swt.events.SelectionEvent;
18 import org.eclipse.swt.graphics.Color;
19 import org.eclipse.swt.graphics.Rectangle;
20 import org.eclipse.swt.layout.FillLayout;
21 import org.eclipse.swt.widgets.Button;
22 import org.eclipse.swt.widgets.Composite;
23 import org.eclipse.swt.widgets.Control;
24 import org.eclipse.swt.widgets.Table;
25 import org.eclipse.swt.widgets.TableColumn;
26 import org.eclipse.swt.widgets.TableItem;
27 import org.eclipse.ui.forms.widgets.Form;
28 import org.eclipse.ui.forms.widgets.FormToolkit;
29 import org.eclipse.ui.forms.widgets.Section;
30 import org.simantics.Simantics;
31 import org.simantics.db.ReadGraph;
32 import org.simantics.db.RequestProcessor;
33 import org.simantics.db.Resource;
34 import org.simantics.db.WriteGraph;
35 import org.simantics.db.common.request.PossibleIndexRoot;
36 import org.simantics.db.common.request.UniqueRead;
37 import org.simantics.db.common.request.WriteRequest;
38 import org.simantics.db.exception.DatabaseException;
39 import org.simantics.layer0.Layer0;
40 import org.simantics.modeling.userComponent.ComponentTypeCommands;
41 import org.simantics.scl.runtime.function.Function4;
42 import org.simantics.structural.stubs.StructuralResource2;
44 public class DerivedPropertiesSection implements ComponentTypeViewerSection {
45 private static final String[] COLUMN_NAMES =
46 new String[] {"Name", "Type", "Expression", "Label", "Description"};
47 private static final int[] COLUMN_LENGTHS =
48 new int[] { 120, 100, 100, 100, 100 };
49 private static final int[] COLUMN_WEIGHTS =
50 new int[] { 0, 0, 100, 0, 0 };
51 private static Function4<RequestProcessor, Resource, Resource, String, String> VALIDATE_MONITOR_EXPRESSION =
52 new Function4<RequestProcessor, Resource, Resource, String, String>() {
54 public String apply(RequestProcessor p0, Resource p1, Resource p2, String p3) {
55 return validateMonitorExpression(p0, p1, p2, p3);
59 ComponentTypeViewerData data;
61 TableColumn[] columns;
64 Button removeProperty;
68 public DerivedPropertiesSection(ComponentTypeViewerData data) {
70 FormToolkit tk = data.tk;
71 Form form = data.form;
72 section = tk.createSection(form.getBody(), Section.TITLE_BAR | Section.EXPANDED);
73 section.setLayout(new FillLayout());
74 section.setText("Derived properties");
76 Composite sectionBody = tk.createComposite(section);
77 GridLayoutFactory.fillDefaults().numColumns(2).applyTo(sectionBody);
78 section.setClient(sectionBody);
80 Composite tableComposite = tk.createComposite(sectionBody);
81 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(tableComposite);
82 TableColumnLayout tcl = new TableColumnLayout();
83 tableComposite.setLayout(tcl);
85 table = tk.createTable(tableComposite, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
86 table.setLinesVisible(true);
87 table.setHeaderVisible(true);
89 columns = new TableColumn[COLUMN_NAMES.length];
90 for(int i=0;i<COLUMN_NAMES.length;++i) {
91 TableColumn column = new TableColumn(table, SWT.NONE);
93 tcl.setColumnData(column, new ColumnWeightData(COLUMN_WEIGHTS[i], COLUMN_LENGTHS[i], true));
94 column.setText(COLUMN_NAMES[i]);
98 editor = new TableEditor(table);
99 editor.grabHorizontal = true;
100 editor.grabVertical = true;
101 editor.horizontalAlignment = SWT.LEFT;
102 table.addMouseListener(new MouseAdapter() {
104 public void mouseDown(MouseEvent e) {
105 // Clean up any previous editor control
106 Control oldEditor = editor.getEditor();
107 if (oldEditor != null) oldEditor.dispose();
113 Rectangle tableBounds = table.getClientArea();
114 int rx = e.x - tableBounds.x;
115 int ry = e.y - tableBounds.y;
118 TableItem selectedItem = null;
119 int selectedColumn = -1;
120 Rectangle selectedItemBounds = null;
121 for(TableItem item : table.getItems()) {
122 for(int column = 0;column < COLUMN_NAMES.length;++column) {
123 Rectangle bounds = item.getBounds(column);
124 if(bounds.contains(rx, ry)) {
125 selectedItemBounds = bounds;
127 selectedColumn = column;
132 if(selectedItem == null) {
137 final int column = selectedColumn;
138 final ComponentTypeViewerPropertyInfo propertyInfo = (ComponentTypeViewerPropertyInfo)selectedItem.getData();
139 final Resource resource = propertyInfo.resource;
142 data.editName(table, editor, propertyInfo, selectedItem, column, ComponentTypeViewerData.PROPERTY_NAME_PATTERN);
146 data.editType(table, editor, propertyInfo, selectedItem, column, false);
150 data.editValue(table, editor, propertyInfo, selectedItem, column, propertyInfo.immutable ? null : new StringWriter() {
152 public void perform(WriteGraph graph, String newValue) throws DatabaseException {
153 ComponentTypeCommands.setMonitorExpression(graph, data.componentType, resource, newValue);
155 }, VALIDATE_MONITOR_EXPRESSION);
159 // editUnit(table2, editor2, propertyInfo, selectedItem, column);
163 data.editValue(table, editor, propertyInfo, selectedItem, column, propertyInfo.immutable ? null : new StringWriter() {
165 public void perform(WriteGraph graph, String newValue) throws DatabaseException {
166 graph.markUndoPoint();
167 String value = newValue.isEmpty() ? null : newValue;
168 ComponentTypeCommands.setLabel(graph, resource, value);
174 data.editMultilineText(table, editor, propertyInfo, selectedItem, selectedItemBounds, column, new StringWriter() {
176 public void perform(WriteGraph graph, String newValue) throws DatabaseException {
177 graph.markUndoPoint();
178 String value = newValue.isEmpty() ? null : newValue;
179 ComponentTypeCommands.setDescription(graph, resource, value);
190 Composite buttons = tk.createComposite(sectionBody);
191 GridDataFactory.fillDefaults().applyTo(buttons);
192 GridLayoutFactory.fillDefaults().applyTo(buttons);
194 newProperty = tk.createButton(buttons, "New property", SWT.PUSH);
195 GridDataFactory.fillDefaults().applyTo(newProperty);
196 removeProperty = tk.createButton(buttons, "Remove property", SWT.PUSH);
197 GridDataFactory.fillDefaults().applyTo(removeProperty);
201 newProperty.addSelectionListener(new SelectionAdapter() {
203 public void widgetSelected(SelectionEvent e) {
204 if(editor.getEditor() != null)
205 editor.getEditor().dispose();
206 Simantics.getSession().async(new WriteRequest() {
208 public void perform(WriteGraph graph)
209 throws DatabaseException {
210 ComponentTypeCommands.createMonitorPropertyWithDefaults(graph, data.componentType);
216 removeProperty.addSelectionListener(new SelectionAdapter() {
218 public void widgetSelected(SelectionEvent e) {
219 if(editor.getEditor() != null)
220 editor.getEditor().dispose();
221 final List<Resource> propertiesToBeRemoved =
223 for(TableItem item : table.getSelection())
224 propertiesToBeRemoved.add(((ComponentTypeViewerPropertyInfo)item.getData()).resource);
225 //System.out.println("remove " + propertiesToBeRemoved.size() + " resources");
226 if(!propertiesToBeRemoved.isEmpty())
227 Simantics.getSession().async(new WriteRequest() {
229 public void perform(WriteGraph graph)
230 throws DatabaseException {
231 graph.markUndoPoint();
232 for(Resource property : propertiesToBeRemoved)
233 ComponentTypeCommands.removeProperty(graph, data.componentType, property);
241 public void setReadOnly(boolean readOnly) {
242 boolean e = !readOnly;
243 newProperty.setEnabled(e);
244 removeProperty.setEnabled(e);
247 public static String validateMonitorExpression(final RequestProcessor processor, final Resource componentType, final Resource relation, final String expression) {
249 if (expression.trim().isEmpty()) {
250 return "Expression is empty.";
253 if (expression.trim().isEmpty()) {
254 return "Expression is empty.";
257 return processor.sync(new UniqueRead<String>() {
260 public String perform(ReadGraph graph) throws DatabaseException {
262 StructuralResource2 STR = StructuralResource2.getInstance(graph);
264 Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(componentType));
266 for(Resource literal : graph.getAssertedObjects(componentType, relation)) {
270 if(graph.isInstanceOf(componentType, STR.ProceduralComponentType)) {
271 //Layer0 L0 = Layer0.getInstance(graph);
272 //Resource environment = graph.getPossibleObject(literal, L0.SCLValue_environment);
273 //ContextModule context = graph.sync(new TypeMonitorContextRequest(componentType));
274 //String SCLMain = graph.syncRequest(new SCLMainModuleRequest(indexRoot));
275 //CompilationContext cc = new CompilationContext(environment, context, SCLMain);
276 //graph.syncRequest(new ActualCompileRequest(expression, cc), TransientCacheListener.<CompiledExpression>instance());
278 //CompilationContext cc = new CompileSCLMonitorRequest(literal, componentType, indexRoot).getContext(graph);
279 //graph.syncRequest(new ActualCompileRequest(expression, cc), TransientCacheListener.<CompiledExpression>instance());
280 //graph.syncRequest(new CompileSCLMonitorRequest(graph, context));
283 } catch (Exception e) {
284 String msg = e.getMessage();
285 int index = msg.indexOf(":");
286 if(index > 0) msg = msg.substring(index);
297 } catch (DatabaseException e) {
306 public void update(ComponentTypePropertiesResult result) {
307 if (table.isDisposed())
310 Set<ComponentTypeViewerPropertyInfo> selected = new HashSet<>();
311 List<TableItem> selectedItems = new ArrayList<TableItem>(selected.size());
312 for (int i : table.getSelectionIndices()) {
313 TableItem item = table.getItem(i);
314 selected.add((ComponentTypeViewerPropertyInfo) item.getData());
317 int topIndex = table.getTopIndex();
319 if(editor.getEditor() != null)
320 editor.getEditor().dispose();
322 for(ComponentTypeViewerPropertyInfo info : result.getProperties()) {
323 boolean immutable = result.isImmutable() || info.immutable;
324 Color fg = immutable ? table.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY) : null;
325 if(info.sectionSpecificData != MONITOR)
328 TableItem item = new TableItem(table, SWT.NONE);
330 item.setText(0, info.valid != null ? info.name + " (!)" : info.name);
331 item.setText(1, info.type);
332 item.setText(2, info.expression);
333 //item.setText(3, unitStr(info));
334 item.setText(3, info.label);
335 item.setText(4, info.description);
337 item.setForeground(fg);
341 if (selected.contains(info))
342 selectedItems.add(item);
345 table.setTopIndex(topIndex);
346 table.setSelection(selectedItems.toArray(new TableItem[selectedItems.size()]));
351 public Section getSection() {
356 public double getPriority() {
360 private static final Object MONITOR = new Object();
363 public Object getSectionSpecificData(ReadGraph graph,
364 ComponentTypeViewerPropertyInfo info) throws DatabaseException {
365 Layer0 L0 = Layer0.getInstance(graph);
366 StructuralResource2 STR = StructuralResource2.getInstance(graph);
367 Resource range = graph.getPossibleObject(info.resource, L0.HasRange);
368 if(range != null && graph.isInstanceOf(range, STR.MonitorValueType))
375 public double getDataPriority() {