1 package org.simantics.sysdyn.ui.properties.widgets;
\r
3 import java.util.ArrayList;
\r
4 import java.util.Iterator;
\r
5 import java.util.Map;
\r
6 import java.util.StringTokenizer;
\r
7 import java.util.LinkedHashMap;
\r
9 import org.eclipse.swt.widgets.Combo;
\r
10 import org.eclipse.swt.widgets.Composite;
\r
11 import org.simantics.browsing.ui.swt.widgets.TrackedCombo;
\r
12 import org.simantics.browsing.ui.swt.widgets.impl.ComboModifyListenerImpl;
\r
13 import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;
\r
14 import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent;
\r
15 import org.simantics.browsing.ui.swt.widgets.impl.Widget;
\r
16 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;
\r
17 import org.simantics.db.ReadGraph;
\r
18 import org.simantics.db.Resource;
\r
19 import org.simantics.db.Session;
\r
20 import org.simantics.db.VirtualGraph;
\r
21 import org.simantics.db.WriteGraph;
\r
22 import org.simantics.db.common.request.WriteRequest;
\r
23 import org.simantics.db.common.utils.NameUtils;
\r
24 import org.simantics.db.common.utils.OrderedSetUtils;
\r
25 import org.simantics.db.exception.DatabaseException;
\r
26 import org.simantics.db.management.ISessionContext;
\r
27 import org.simantics.db.procedure.Listener;
\r
28 import org.simantics.db.service.VirtualGraphSupport;
\r
29 import org.simantics.layer0.Layer0;
\r
30 import org.simantics.sysdyn.SysdynResource;
\r
31 import org.simantics.sysdyn.ui.utils.VariableNameUtils;
\r
33 public class ArrayExpressionCombo extends TrackedCombo {
\r
35 int lastSelectedIndex = -2;
\r
37 public ArrayExpressionCombo(Composite parent, WidgetSupport support,
\r
39 super(parent, support, style);
\r
42 this.setInputValidator(new VariableNameValidator(support));
\r
45 this.setItemFactory(new ReadFactoryImpl<Resource, Map<String, Object>>() {
\r
48 public Map<String, Object> perform(ReadGraph graph, final Resource input) throws DatabaseException {
\r
49 Map<String, Object> map = new LinkedHashMap<String, Object>();
\r
54 Layer0 l0 = Layer0.getInstance(graph);
\r
55 String name = graph.getPossibleRelatedValue(input, l0.HasName);
\r
59 SysdynResource sr = SysdynResource.getInstance(graph);
\r
61 String defaultRange = getDefaultRange(graph, input);
\r
62 for(Resource expression : getExpressions(graph, input)) {
\r
63 String arrayRange = graph.getPossibleRelatedValue(expression, sr.Expression_arrayRange);
\r
64 if(arrayRange != null) {
\r
65 map.put(name + arrayRange, expression);
\r
66 } else if(defaultRange != null) {
\r
67 map.put(name + defaultRange, expression);
\r
69 map.put(name, expression);
\r
73 map.put(name, input);
\r
81 this.setSelectionFactory(new ReadFactoryImpl<Resource, String>() {
\r
84 public String perform(ReadGraph graph, final Resource input) throws DatabaseException {
\r
85 String name = graph.getPossibleRelatedValue(input, Layer0.getInstance(graph).HasName);
\r
89 String defaultRange = getDefaultRange(graph, input);
\r
90 if(defaultRange == null)
\r
93 SysdynResource sr = SysdynResource.getInstance(graph);
\r
95 Resource activeExpression = graph.getPossibleObject(input, sr.IndependentVariable_activeExpression);
\r
96 Resource expression;
\r
97 if(activeExpression == null) {
\r
98 ArrayList<Resource> expressions = getExpressions(graph, input);
\r
99 if(expressions == null || expressions.isEmpty())
\r
101 expression = expressions.get(0);
\r
103 expression = activeExpression;
\r
105 String range = graph.getPossibleRelatedValue(expression, sr.Expression_arrayRange);
\r
107 return name + range;
\r
109 return name + defaultRange;
\r
113 this.addModifyListener(new NameAndArrayRangeModifyListener(support));
\r
118 public void setInput(ISessionContext context, Object input) {
\r
119 super.setInput(context, input);
\r
121 if(selectionFactory != null) {
\r
122 selectionFactory.listen(context, input, new Listener<String>() {
\r
125 public void execute(final String result) {
\r
126 if(getWidget().isDisposed()) return;
\r
127 getWidget().getDisplay().asyncExec(new Runnable() {
\r
130 public void run() {
\r
131 Combo combo = getWidget();
\r
132 if(combo != null && !combo.isDisposed() && result != null) {
\r
133 Object o = getWidget().getData(result);
\r
135 lastSelectedIndex = (Integer)o;
\r
143 public void exception(Throwable t) {
\r
144 t.printStackTrace();
\r
148 public boolean isDisposed() {
\r
149 return getWidget().isDisposed();
\r
156 private ArrayList<Resource> getExpressions(ReadGraph graph, Resource variable) throws DatabaseException {
\r
157 SysdynResource sr = SysdynResource.getInstance(graph);
\r
158 Resource hasExpressions = graph.getPossibleObject(variable, sr.Variable_expressions);
\r
159 if(hasExpressions == null)
\r
160 return new ArrayList<Resource>();
\r
162 return new ArrayList<Resource>(OrderedSetUtils.toList(graph, hasExpressions));
\r
165 public static String getDefaultRange(ReadGraph graph, Resource variable) throws DatabaseException {
\r
166 SysdynResource sr = SysdynResource.getInstance(graph);
\r
167 Resource hasArrayIndexes = graph.getPossibleObject(variable, sr.Variable_arrayIndexes);
\r
169 if(hasArrayIndexes == null)
\r
172 Iterator<Resource> iterator = OrderedSetUtils.iterator(graph, hasArrayIndexes);
\r
173 if(!iterator.hasNext())
\r
176 StringBuilder sb = new StringBuilder();
\r
179 while(iterator.hasNext()) {
\r
180 sb.append(NameUtils.getSafeName(graph, iterator.next()));
\r
181 if(iterator.hasNext()) {
\r
186 return sb.toString();
\r
189 private class NameAndArrayRangeModifyListener extends ComboModifyListenerImpl<Resource> implements Widget {
\r
191 Resource lastExpression;
\r
193 public NameAndArrayRangeModifyListener(WidgetSupport support) {
\r
194 support.register(this);
\r
198 public void setInput(ISessionContext context, Object input) {
\r
199 super.setInput(context, input);
\r
203 public void modifyText(TrackedModifyEvent e) {
\r
205 Combo combo = (Combo)e.getWidget();
\r
206 LinkedHashMap<?, ?> data = (LinkedHashMap<?, ?>) combo.getData();
\r
208 Resource expression = (Resource) data.get(combo.getText());
\r
209 if(expression != null) {
\r
210 lastExpression = expression;
\r
211 lastSelectedIndex = combo.getSelectionIndex();
\r
213 for(Object key : data.keySet()) {
\r
214 int index = lastSelectedIndex < 0 ? 0 : lastSelectedIndex;
\r
215 if((Integer)combo.getData((String)key) == index) {
\r
216 lastExpression = (Resource) data.get((String)key);
\r
222 super.modifyText(e);
\r
226 public void applyText(WriteGraph graph, final Resource variable, String text)
\r
227 throws DatabaseException {
\r
228 StringTokenizer st = new StringTokenizer(text, "[]");
\r
229 final String newName = st.nextToken();
\r
230 String range = null;
\r
231 if(st.hasMoreTokens()) {
\r
232 range = st.nextToken();
\r
234 String originalName = graph.getRelatedValue(variable, Layer0.getInstance(graph).HasName);
\r
235 if(!originalName.equals(newName)) {
\r
236 VariableNameUtils.renameInEquations(graph, variable, originalName, newName);
\r
237 graph.claimLiteral(variable, Layer0.getInstance(graph).HasName, newName);
\r
240 SysdynResource sr = SysdynResource.getInstance(graph);
\r
242 if(range != null && lastExpression != null) {
\r
243 String oldRange = graph.getPossibleRelatedValue(lastExpression, sr.Expression_arrayRange);
\r
244 if(oldRange == null || !range.equals(oldRange)) {
\r
245 graph.claimLiteral(lastExpression, sr.Expression_arrayRange, "[" + range + "]");
\r
247 } else if (range == null && lastExpression != null && graph.hasStatement(lastExpression, sr.Expression_arrayRange)) {
\r
248 graph.deny(lastExpression, sr.Expression_arrayRange);
\r
251 Resource activeExpression = graph.getPossibleObject(variable, sr.IndependentVariable_activeExpression);
\r
253 if(lastExpression != null && !lastExpression.equals(activeExpression)) {
\r
254 VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);
\r
255 final Session session = graph.getSession();
\r
256 session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("expressions")) {
\r
258 public void perform(WriteGraph graph) throws DatabaseException {
\r
259 VirtualGraph runtime = graph.getService(VirtualGraph.class);
\r
260 session.asyncRequest(new WriteRequest(runtime) {
\r
262 public void perform(WriteGraph graph) throws DatabaseException {
\r
263 SysdynResource sr = SysdynResource.getInstance(graph);
\r
264 if(graph.hasStatement(variable, sr.IndependentVariable_activeExpression))
\r
265 graph.deny(variable, sr.IndependentVariable_activeExpression);
\r
266 graph.claim(variable, sr.IndependentVariable_activeExpression, lastExpression);
\r