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