1 /*******************************************************************************
\r
2 * Copyright (c) 2012 Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.modeling.ui.componentTypeEditor;
\r
14 import java.util.ArrayList;
\r
15 import java.util.Collections;
\r
16 import java.util.List;
\r
18 import org.eclipse.jface.dialogs.IMessageProvider;
\r
19 import org.eclipse.jface.resource.JFaceResources;
\r
20 import org.eclipse.jface.resource.LocalResourceManager;
\r
21 import org.eclipse.jface.resource.ResourceManager;
\r
22 import org.eclipse.swt.SWT;
\r
23 import org.eclipse.swt.events.SelectionAdapter;
\r
24 import org.eclipse.swt.events.SelectionEvent;
\r
25 import org.eclipse.swt.layout.FormAttachment;
\r
26 import org.eclipse.swt.layout.FormData;
\r
27 import org.eclipse.swt.layout.FormLayout;
\r
28 import org.eclipse.swt.widgets.Composite;
\r
29 import org.eclipse.swt.widgets.Sash;
\r
30 import org.eclipse.ui.forms.IMessageManager;
\r
31 import org.eclipse.ui.forms.widgets.Form;
\r
32 import org.eclipse.ui.forms.widgets.FormToolkit;
\r
33 import org.osgi.framework.BundleContext;
\r
34 import org.osgi.framework.InvalidSyntaxException;
\r
35 import org.osgi.framework.ServiceReference;
\r
36 import org.simantics.Simantics;
\r
37 import org.simantics.databoard.Bindings;
\r
38 import org.simantics.databoard.binding.Binding;
\r
39 import org.simantics.databoard.binding.error.BindingException;
\r
40 import org.simantics.databoard.type.Datatype;
\r
41 import org.simantics.databoard.type.NumberType;
\r
42 import org.simantics.db.ReadGraph;
\r
43 import org.simantics.db.Resource;
\r
44 import org.simantics.db.common.NamedResource;
\r
45 import org.simantics.db.common.request.UniqueRead;
\r
46 import org.simantics.db.common.utils.NameUtils;
\r
47 import org.simantics.db.exception.DatabaseException;
\r
48 import org.simantics.db.procedure.Listener;
\r
49 import org.simantics.db.request.Read;
\r
50 import org.simantics.db.service.XSupport;
\r
51 import org.simantics.layer0.Layer0;
\r
52 import org.simantics.modeling.ui.Activator;
\r
53 import org.simantics.operation.Layer0X;
\r
54 import org.simantics.structural.stubs.StructuralResource2;
\r
55 import org.simantics.utils.ui.ErrorLogger;
\r
56 import org.simantics.utils.ui.SWTUtils;
\r
58 public class ComponentTypeViewer {
\r
60 ComponentTypeViewerData data;
\r
62 ResourceManager resourceManager;
\r
64 ArrayList<ComponentTypeViewerSection> sections = new ArrayList<ComponentTypeViewerSection>(3);
\r
66 public ComponentTypeViewer(Composite parent, Resource _componentType, String formTitle) {
\r
68 FormToolkit tk = new FormToolkit(parent.getDisplay());
\r
69 Form form = tk.createForm(parent);
\r
70 tk.decorateFormHeading(form);
\r
71 resourceManager = new LocalResourceManager(JFaceResources.getResources(), form);
\r
72 form.setText(formTitle);
\r
73 form.setImage(resourceManager.createImage(Activator.COMPONENT_TYPE_ICON));
\r
75 FormLayout layout = new FormLayout();
\r
76 layout.marginBottom = 10;
\r
77 layout.marginTop = 10;
\r
78 layout.marginLeft = 10;
\r
79 layout.marginRight = 10;
\r
80 form.getBody().setLayout(layout);
\r
84 data = new ComponentTypeViewerData(tk, _componentType, form);
\r
88 sections.add(new ConfigurationPropertiesSection(data));
\r
89 sections.add(new DerivedPropertiesSection(data));
\r
91 BundleContext bundleContext = Activator.getContext();
\r
93 ArrayList<ComponentTypeViewerSectionFactory> factories =
\r
94 Simantics.getSession().syncRequest(new Read<ArrayList<ComponentTypeViewerSectionFactory>>() {
\r
96 public ArrayList<ComponentTypeViewerSectionFactory> perform(
\r
97 ReadGraph graph) throws DatabaseException {
\r
98 ArrayList<ComponentTypeViewerSectionFactory> factories =
\r
99 new ArrayList<ComponentTypeViewerSectionFactory>(3);
\r
101 String className = ComponentTypeViewerSectionFactory.class.getName();
\r
102 ServiceReference<?>[] references = bundleContext.getAllServiceReferences(className, null);
\r
103 if(references != null)
\r
104 for(ServiceReference<?> reference : references) {
\r
105 ComponentTypeViewerSectionFactory factory = (ComponentTypeViewerSectionFactory)bundleContext.getService(reference);
\r
106 if(factory.doesSupport(graph, _componentType))
\r
107 factories.add(factory);
\r
109 } catch (InvalidSyntaxException e) {
\r
110 e.printStackTrace();
\r
115 for(ComponentTypeViewerSectionFactory factory : factories)
\r
116 sections.add(factory.create(data));
\r
117 } catch(DatabaseException e) {
\r
118 e.printStackTrace();
\r
121 sections.sort((a,b) -> { return Double.compare(a.getPriority(), b.getPriority()); });
\r
125 Sash[] sashes = new Sash[sections.size()-1];
\r
126 for(int i=0;i<sections.size()-1;++i) {
\r
127 Sash sash = new Sash(form.getBody(), SWT.HORIZONTAL);
\r
128 sash.setBackground(sash.getDisplay().getSystemColor(SWT.COLOR_WHITE));
\r
130 FormData data = new FormData();
\r
131 data.top = new FormAttachment(100*(i+1)/sections.size(), 0);
\r
132 data.left = new FormAttachment(0, 0);
\r
133 data.right = new FormAttachment(100, 0);
\r
135 sash.setLayoutData(data);
\r
137 sash.addSelectionListener(new SelectionAdapter() {
\r
138 public void widgetSelected(SelectionEvent e) {
\r
139 sash.setBounds(e.x, e.y, e.width, e.height);
\r
140 FormData data = new FormData();
\r
141 data.top = new FormAttachment(0, e.y);
\r
142 data.left = new FormAttachment(0, 0);
\r
143 data.right = new FormAttachment(100, 0);
\r
145 sash.setLayoutData(data);
\r
146 form.getBody().layout(true);
\r
151 for(int i=0;i<sections.size();++i) {
\r
153 FormData formData = new FormData();
\r
154 formData.top = i > 0 ? new FormAttachment(sashes[i-1]) : new FormAttachment(0, 0);
\r
155 formData.left = new FormAttachment(0, 0);
\r
156 formData.right = new FormAttachment(100, 0);
\r
157 formData.bottom = i < sections.size()-1
\r
158 ? new FormAttachment(sashes[i]) : new FormAttachment(100, 0);
\r
159 sections.get(i).getSection().setLayoutData(formData);
\r
164 createGraphListener();
\r
167 private void createGraphListener() {
\r
168 Simantics.getSession().asyncRequest(new UniqueRead<ComponentTypePropertiesResult>() {
\r
170 public ComponentTypePropertiesResult perform(ReadGraph graph) throws DatabaseException {
\r
171 List<ComponentTypeViewerPropertyInfo> result = new ArrayList<>();
\r
172 List<NamedResource> connectionPoints = new ArrayList<>();
\r
173 Layer0 L0 = Layer0.getInstance(graph);
\r
174 Layer0X L0X = Layer0X.getInstance(graph);
\r
175 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
176 for(Resource relation : graph.getObjects(data.componentType, L0.DomainOf)) {
\r
177 if(graph.isSubrelationOf(relation, L0.HasProperty)) {
\r
178 String name = graph.getRelatedValue(relation, L0.HasName);
\r
179 String type = graph.getPossibleRelatedValue(relation, L0.RequiresValueType);
\r
180 String label = graph.getPossibleRelatedValue(relation, L0.HasLabel);
\r
183 String description = graph.getPossibleRelatedValue(relation, L0.HasDescription);
\r
184 if (description == null)
\r
186 NumberType numberType = null;
\r
189 String unit = graph.getPossibleRelatedValue(relation, L0X.HasUnit, Bindings.STRING);
\r
190 String defaultValue = "0";
\r
191 String expression = null;
\r
193 for(Resource assertion : graph.getAssertedObjects(data.componentType, relation)) {
\r
195 expression = graph.getPossibleRelatedValue(assertion, L0.SCLValue_expression, Bindings.STRING);
\r
196 if(expression != null) {
\r
197 defaultValue = "=" + expression;
\r
199 Datatype dt = getPossibleDatatype(graph, assertion);
\r
202 if (dt instanceof NumberType)
\r
203 numberType = (NumberType) dt;
\r
204 Binding binding = Bindings.getBinding(dt);
\r
205 Object value = graph.getValue(assertion, binding);
\r
207 defaultValue = binding.toString(value, true);
\r
208 } catch (BindingException e) {
\r
209 ErrorLogger.defaultLogError(e);
\r
212 } catch(DatabaseException e) {
\r
213 ErrorLogger.defaultLogError(e);
\r
217 String valid = expression != null ? DerivedPropertiesSection.validateMonitorExpression(graph, data.componentType, relation, expression) : null;
\r
219 boolean immutable = graph.isImmutable(relation);
\r
220 ComponentTypeViewerPropertyInfo info =
\r
221 new ComponentTypeViewerPropertyInfo(relation, name, type, defaultValue, numberType, unit, label, description, expression, valid, immutable);
\r
223 Object sectionSpecificData = null;
\r
224 double priority = Double.NEGATIVE_INFINITY;
\r
225 for(ComponentTypeViewerSection section : sections) {
\r
226 Object temp = section.getSectionSpecificData(graph, info);
\r
228 double sectionPriority = section.getDataPriority();
\r
229 if(sectionPriority > priority) {
\r
230 sectionSpecificData = temp;
\r
231 priority = sectionPriority;
\r
235 info.sectionSpecificData = sectionSpecificData;
\r
239 } else if (graph.isInstanceOf(relation, STR.ConnectionRelation)) {
\r
240 NamedResource nr = new NamedResource(NameUtils.getSafeName(graph, relation), relation);
\r
241 connectionPoints.add(nr);
\r
244 Collections.sort(result);
\r
245 XSupport xs = graph.peekService(XSupport.class);
\r
246 boolean immutable = xs != null ? xs.getImmutable(data.componentType) : false;
\r
247 return new ComponentTypePropertiesResult(result, connectionPoints, immutable);
\r
249 }, new Listener<ComponentTypePropertiesResult>() {
\r
251 public void execute(final ComponentTypePropertiesResult result) {
\r
252 SWTUtils.asyncExec(data.form.getDisplay(), new Runnable() {
\r
254 public void run() {
\r
255 // Store loaded properties
\r
256 data.properties = result.getProperties().toArray(new ComponentTypeViewerPropertyInfo[result.getProperties().size()]);
\r
257 data.connectionPoints = result.getConnectionPoints().toArray(new NamedResource[result.getConnectionPoints().size()]);
\r
259 for(ComponentTypeViewerSection section : sections)
\r
260 section.update(result);
\r
261 setReadOnly(result.isImmutable());
\r
267 public void exception(Throwable t) {
\r
268 ErrorLogger.defaultLogError(t);
\r
272 public boolean isDisposed() {
\r
273 return data.form.isDisposed();
\r
279 protected Datatype getPossibleDatatype(ReadGraph graph, Resource literal) throws DatabaseException {
\r
280 Binding binding = Bindings.getBindingUnchecked(Datatype.class);
\r
281 for (Resource dataTypeResource : graph.getObjects(literal, Layer0.getInstance(graph).HasDataType)) {
\r
282 Datatype dt = graph.getPossibleValue(dataTypeResource, binding);
\r
289 public void setFocus() {
\r
290 data.form.setFocus();
\r
297 private void setReadOnly(boolean readOnly) {
\r
298 if (readOnly == data.readOnly)
\r
300 data.readOnly = readOnly;
\r
301 for(ComponentTypeViewerSection section : sections)
\r
302 section.setReadOnly(readOnly);
\r
303 IMessageManager mm = data.form.getMessageManager();
\r
305 mm.addMessage("readonly", "(Opened in read-only mode)", null, IMessageProvider.INFORMATION);
\r
307 mm.removeMessage("readonly");
\r