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 Messages.DerivedPropertiesSection_Name,
47 Messages.DerivedPropertiesSection_Type,
48 Messages.DerivedPropertiesSection_Expression,
49 Messages.DerivedPropertiesSection_Unit,
50 Messages.DerivedPropertiesSection_Label,
51 Messages.DerivedPropertiesSection_Description
53 private static final int[] COLUMN_LENGTHS =
54 new int[] { 120, 100, 100, 70, 100, 100 };
55 private static final int[] COLUMN_WEIGHTS =
56 new int[] { 0, 0, 100, 0, 0, 0 };
57 private static Function4<RequestProcessor, Resource, Resource, String, String> VALIDATE_MONITOR_EXPRESSION =
58 new Function4<RequestProcessor, Resource, Resource, String, String>() {
60 public String apply(RequestProcessor p0, Resource p1, Resource p2, String p3) {
61 return validateMonitorExpression(p0, p1, p2, p3);
65 ComponentTypeViewerData data;
67 TableColumn[] columns;
70 Button removeProperty;
74 public DerivedPropertiesSection(ComponentTypeViewerData data) {
76 FormToolkit tk = data.tk;
77 Form form = data.form;
78 section = tk.createSection(form.getBody(), Section.TITLE_BAR | Section.EXPANDED);
79 section.setLayout(new FillLayout());
80 section.setText(Messages.DerivedPropertiesSection_DerivedProperties);
82 Composite sectionBody = tk.createComposite(section);
83 GridLayoutFactory.fillDefaults().numColumns(2).applyTo(sectionBody);
84 section.setClient(sectionBody);
86 Composite tableComposite = tk.createComposite(sectionBody);
87 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(tableComposite);
88 TableColumnLayout tcl = new TableColumnLayout();
89 tableComposite.setLayout(tcl);
91 table = tk.createTable(tableComposite, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
92 table.setLinesVisible(true);
93 table.setHeaderVisible(true);
95 columns = new TableColumn[COLUMN_NAMES.length];
96 for(int i=0;i<COLUMN_NAMES.length;++i) {
97 TableColumn column = new TableColumn(table, SWT.NONE);
99 tcl.setColumnData(column, new ColumnWeightData(COLUMN_WEIGHTS[i], COLUMN_LENGTHS[i], true));
100 column.setText(COLUMN_NAMES[i]);
104 editor = new TableEditor(table);
105 editor.grabHorizontal = true;
106 editor.grabVertical = true;
107 editor.horizontalAlignment = SWT.LEFT;
108 table.addMouseListener(new MouseAdapter() {
110 public void mouseDown(MouseEvent e) {
111 // Clean up any previous editor control
112 Control oldEditor = editor.getEditor();
113 if (oldEditor != null) oldEditor.dispose();
119 Rectangle tableBounds = table.getClientArea();
120 int rx = e.x - tableBounds.x;
121 int ry = e.y - tableBounds.y;
124 TableItem selectedItem = null;
125 int selectedColumn = -1;
126 Rectangle selectedItemBounds = null;
127 for(TableItem item : table.getItems()) {
128 for(int column = 0;column < COLUMN_NAMES.length;++column) {
129 Rectangle bounds = item.getBounds(column);
130 if(bounds.contains(rx, ry)) {
131 selectedItemBounds = bounds;
133 selectedColumn = column;
138 if(selectedItem == null) {
143 final int column = selectedColumn;
144 final ComponentTypeViewerPropertyInfo propertyInfo = (ComponentTypeViewerPropertyInfo)selectedItem.getData();
145 final Resource resource = propertyInfo.resource;
148 data.editName(table, editor, propertyInfo, selectedItem, column, ComponentTypeViewerData.PROPERTY_NAME_PATTERN);
152 data.editType(table, editor, propertyInfo, selectedItem, column, false);
156 data.editValue(table, editor, propertyInfo, selectedItem, column, propertyInfo.immutable ? null : new StringWriter() {
158 public void perform(WriteGraph graph, String newValue) throws DatabaseException {
159 ComponentTypeCommands.setMonitorExpression(graph, data.componentType, resource, newValue);
161 }, VALIDATE_MONITOR_EXPRESSION);
165 data.editUnit(table, editor, propertyInfo, selectedItem, column);
169 data.editValue(table, editor, propertyInfo, selectedItem, column, propertyInfo.immutable ? null : new StringWriter() {
171 public void perform(WriteGraph graph, String newValue) throws DatabaseException {
172 graph.markUndoPoint();
173 String value = newValue.isEmpty() ? null : newValue;
174 ComponentTypeCommands.setLabel(graph, resource, value);
180 data.editMultilineText(table, editor, propertyInfo, selectedItem, selectedItemBounds, column, new StringWriter() {
182 public void perform(WriteGraph graph, String newValue) throws DatabaseException {
183 graph.markUndoPoint();
184 String value = newValue.isEmpty() ? null : newValue;
185 ComponentTypeCommands.setDescription(graph, resource, value);
196 Composite buttons = tk.createComposite(sectionBody);
197 GridDataFactory.fillDefaults().applyTo(buttons);
198 GridLayoutFactory.fillDefaults().applyTo(buttons);
200 newProperty = tk.createButton(buttons, Messages.DerivedPropertiesSection_NewProperty, SWT.PUSH);
201 GridDataFactory.fillDefaults().applyTo(newProperty);
202 removeProperty = tk.createButton(buttons, Messages.DerivedPropertiesSection_RemoveProperty, SWT.PUSH);
203 GridDataFactory.fillDefaults().applyTo(removeProperty);
207 newProperty.addSelectionListener(new SelectionAdapter() {
209 public void widgetSelected(SelectionEvent e) {
210 if(editor.getEditor() != null)
211 editor.getEditor().dispose();
212 Simantics.getSession().async(new WriteRequest() {
214 public void perform(WriteGraph graph)
215 throws DatabaseException {
216 ComponentTypeCommands.createMonitorPropertyWithDefaults(graph, data.componentType);
222 removeProperty.addSelectionListener(new SelectionAdapter() {
224 public void widgetSelected(SelectionEvent e) {
225 if(editor.getEditor() != null)
226 editor.getEditor().dispose();
227 final List<Resource> propertiesToBeRemoved =
229 for(TableItem item : table.getSelection())
230 propertiesToBeRemoved.add(((ComponentTypeViewerPropertyInfo)item.getData()).resource);
231 //System.out.println("remove " + propertiesToBeRemoved.size() + " resources");
232 if(!propertiesToBeRemoved.isEmpty())
233 Simantics.getSession().async(new WriteRequest() {
235 public void perform(WriteGraph graph)
236 throws DatabaseException {
237 graph.markUndoPoint();
238 for(Resource property : propertiesToBeRemoved)
239 ComponentTypeCommands.removeProperty(graph, data.componentType, property);
247 public void setReadOnly(boolean readOnly) {
248 boolean e = !readOnly;
249 newProperty.setEnabled(e);
250 removeProperty.setEnabled(e);
253 public static String validateMonitorExpression(final RequestProcessor processor, final Resource componentType, final Resource relation, final String expression) {
255 if (expression.trim().isEmpty()) {
256 return Messages.DerivedPropertiesSection_ExpressionIsEmpty;
259 if (expression.trim().isEmpty()) {
260 return Messages.DerivedPropertiesSection_ExpressionIsEmpty;
263 return processor.sync(new UniqueRead<String>() {
266 public String perform(ReadGraph graph) throws DatabaseException {
268 StructuralResource2 STR = StructuralResource2.getInstance(graph);
270 Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(componentType));
272 for(Resource literal : graph.getAssertedObjects(componentType, relation)) {
276 if(graph.isInstanceOf(componentType, STR.ProceduralComponentType)) {
277 //Layer0 L0 = Layer0.getInstance(graph);
278 //Resource environment = graph.getPossibleObject(literal, L0.SCLValue_environment);
279 //ContextModule context = graph.sync(new TypeMonitorContextRequest(componentType));
280 //String SCLMain = graph.syncRequest(new SCLMainModuleRequest(indexRoot));
281 //CompilationContext cc = new CompilationContext(environment, context, SCLMain);
282 //graph.syncRequest(new ActualCompileRequest(expression, cc), TransientCacheListener.<CompiledExpression>instance());
284 //CompilationContext cc = new CompileSCLMonitorRequest(literal, componentType, indexRoot).getContext(graph);
285 //graph.syncRequest(new ActualCompileRequest(expression, cc), TransientCacheListener.<CompiledExpression>instance());
286 //graph.syncRequest(new CompileSCLMonitorRequest(graph, context));
289 } catch (Exception e) {
290 String msg = e.getMessage();
291 int index = msg.indexOf(":"); //$NON-NLS-1$
292 if(index > 0) msg = msg.substring(index);
303 } catch (DatabaseException e) {
312 public void update(ComponentTypePropertiesResult result) {
313 if (table.isDisposed())
316 Set<ComponentTypeViewerPropertyInfo> selected = new HashSet<>();
317 List<TableItem> selectedItems = new ArrayList<TableItem>(selected.size());
318 for (int i : table.getSelectionIndices()) {
319 TableItem item = table.getItem(i);
320 selected.add((ComponentTypeViewerPropertyInfo) item.getData());
323 int topIndex = table.getTopIndex();
325 if(editor.getEditor() != null)
326 editor.getEditor().dispose();
328 for(ComponentTypeViewerPropertyInfo info : result.getProperties()) {
329 boolean immutable = result.isImmutable() || info.immutable;
330 Color fg = immutable ? table.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY) : null;
331 if(info.sectionSpecificData != MONITOR)
334 TableItem item = new TableItem(table, SWT.NONE);
336 item.setText(0, info.valid != null ? info.name + " (!)" : info.name); //$NON-NLS-1$
337 item.setText(1, info.type);
338 item.setText(2, info.expression);
339 item.setText(3, info.unitString());
340 item.setText(4, info.label);
341 item.setText(5, info.description);
343 item.setForeground(fg);
347 if (selected.contains(info))
348 selectedItems.add(item);
351 table.setTopIndex(topIndex);
352 table.setSelection(selectedItems.toArray(new TableItem[selectedItems.size()]));
357 public Section getSection() {
362 public double getPriority() {
366 private static final Object MONITOR = new Object();
369 public Object getSectionSpecificData(ReadGraph graph,
370 ComponentTypeViewerPropertyInfo info) throws DatabaseException {
371 Layer0 L0 = Layer0.getInstance(graph);
372 StructuralResource2 STR = StructuralResource2.getInstance(graph);
373 Resource range = graph.getPossibleObject(info.resource, L0.HasRange);
374 if(range != null && graph.isInstanceOf(range, STR.MonitorValueType))
381 public double getDataPriority() {