1 /*******************************************************************************
\r
2 * Copyright (c) 2010 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.sysdyn.ui.properties.widgets;
\r
14 import java.text.Collator;
\r
15 import java.util.ArrayList;
\r
16 import java.util.Collections;
\r
17 import java.util.HashSet;
\r
18 import java.util.Locale;
\r
19 import java.util.concurrent.CopyOnWriteArrayList;
\r
21 import org.eclipse.jface.layout.GridDataFactory;
\r
22 import org.eclipse.jface.layout.GridLayoutFactory;
\r
23 import org.eclipse.jface.resource.JFaceResources;
\r
24 import org.eclipse.jface.resource.LocalResourceManager;
\r
25 import org.eclipse.jface.viewers.IStructuredSelection;
\r
26 import org.eclipse.swt.SWT;
\r
27 import org.eclipse.swt.events.FocusListener;
\r
28 import org.eclipse.swt.events.MouseListener;
\r
29 import org.eclipse.swt.widgets.Composite;
\r
30 import org.eclipse.swt.widgets.TabFolder;
\r
31 import org.eclipse.swt.widgets.TabItem;
\r
32 import org.eclipse.swt.widgets.Table;
\r
33 import org.eclipse.swt.widgets.TableItem;
\r
34 import org.simantics.browsing.ui.swt.widgets.impl.Widget;
\r
35 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;
\r
36 import org.simantics.db.AsyncReadGraph;
\r
37 import org.simantics.db.ReadGraph;
\r
38 import org.simantics.db.Resource;
\r
39 import org.simantics.db.exception.DatabaseException;
\r
40 import org.simantics.db.layer0.request.PossibleModel;
\r
41 import org.simantics.db.management.ISessionContext;
\r
42 import org.simantics.db.procedure.AsyncListener;
\r
43 import org.simantics.db.request.Read;
\r
44 import org.simantics.layer0.Layer0;
\r
45 import org.simantics.sysdyn.SysdynResource;
\r
46 import org.simantics.sysdyn.ui.properties.widgets.expressions.Function;
\r
47 import org.simantics.sysdyn.ui.validation.ValidationUtils;
\r
48 import org.simantics.ui.SimanticsUI;
\r
49 import org.simantics.utils.ui.ISelectionUtils;
\r
51 public class ShortcutTabWidget implements Widget {
\r
53 TabFolder tabFolder;
\r
56 Table variableTable;
\r
57 Table functionTable;
\r
58 Composite composite;
\r
61 CopyOnWriteArrayList<Runnable> dependencyListeners =
\r
62 new CopyOnWriteArrayList<Runnable>();
\r
64 private final LocalResourceManager resourceManager;
\r
66 public ShortcutTabWidget(Composite parent, WidgetSupport support, int style) {
\r
68 support.register(this);
\r
70 composite = new Composite(parent, style);
\r
71 GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite);
\r
73 tabFolder = new TabFolder (composite, SWT.NONE);
\r
74 GridDataFactory.fillDefaults().grab(false, true).applyTo(tabFolder);
\r
75 GridLayoutFactory.fillDefaults().applyTo(tabFolder);
\r
76 variables = new TabItem(tabFolder, SWT.NULL);
\r
77 variables.setText("Variables");
\r
78 variableTable = new Table (tabFolder, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION | SWT.NO_FOCUS | SWT.HIDE_SELECTION);
\r
80 variables.setControl(variableTable);
\r
82 functions = new TabItem(tabFolder, SWT.NULL);
\r
83 functions.setText("Functions");
\r
85 functionTable = new Table (tabFolder, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION | SWT.NO_FOCUS | SWT.HIDE_SELECTION);
\r
87 // Create a ResourceManager to dispose images when the widget is disposed.
\r
88 this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), functionTable);
\r
90 functions.setControl(functionTable);
\r
92 // Add the functions only after we know which variable is connected to this widget.
\r
95 public Composite getWidget() {
\r
99 private void addFunctions(Resource model) {
\r
102 ArrayList<Function> functionList = Function.getUserDefinedFunctions(model);
\r
103 functionList.addAll(Function.getSharedFunctions(model));
\r
104 functionList.addAll(Function.getAllBuiltInFunctions());
\r
106 Collections.sort(functionList);
\r
108 for(Function function : functionList){
\r
109 item = new TableItem(functionTable, SWT.NONE);
\r
110 item.setText(function.getName() + "()");
\r
111 item.setData(function.getName() + "(" + function.getParameterList() + ")");
\r
112 item.setImage(Function.getImage(this.resourceManager, function));
\r
118 public void setInput(ISessionContext context, Object input) {
\r
119 if(input instanceof IStructuredSelection) {
\r
120 final Resource variable = ISelectionUtils.filterSingleSelection(input, Resource.class);
\r
121 if(variable != null) {
\r
123 // Fill the function table
\r
125 Resource model = SimanticsUI.getSession().syncRequest(new Read<Resource>() {
\r
128 public Resource perform(ReadGraph graph) throws DatabaseException {
\r
129 return graph.syncRequest(new PossibleModel(variable));
\r
132 addFunctions(model);
\r
133 } catch (DatabaseException e) {
\r
134 e.printStackTrace();
\r
137 // Fill the variable table
\r
138 SimanticsUI.getSession().asyncRequest(new Read<HashSet<String>>() {
\r
141 public HashSet<String> perform(ReadGraph graph)
\r
142 throws DatabaseException {
\r
143 return ValidationUtils.getDependencies(graph, variable);
\r
145 }, new AsyncListener<HashSet<String>>() {
\r
148 public void execute(AsyncReadGraph graph,
\r
149 HashSet<String> result) {
\r
151 final HashSet<String> dependencies = result;
\r
152 variableTable.getDisplay().asyncExec(new Runnable() {
\r
155 public void run() {
\r
156 if(variableTable.isDisposed()) return;
\r
158 TableItem[] items = variableTable.getItems();
\r
160 // Remove deleted dependencies and create the list of current dependencies (itemStrings)
\r
161 ArrayList<String> itemStrings = new ArrayList<String>();
\r
162 for(TableItem i : items) {
\r
163 String text = i.getText();
\r
164 if(dependencies.contains(text))
\r
165 itemStrings.add(text);
\r
167 variableTable.remove(variableTable.indexOf(i));
\r
170 // Add all new dependencies
\r
172 for(String d : dependencies) {
\r
173 if(!itemStrings.contains(d)) {
\r
174 item = new TableItem(variableTable, SWT.NONE);
\r
182 String selfName = getName();
\r
184 // Time and self are not added if selfName (we have an error or a stock).
\r
185 if (selfName != null)
\r
187 item = new TableItem(variableTable, SWT.NONE);
\r
188 item.setText(selfName);
\r
189 item.setData(selfName);
\r
191 item = new TableItem(variableTable, SWT.NONE);
\r
192 item.setText("time");
\r
193 item.setData("time");
\r
196 synchronized(dependencyListeners) {
\r
197 for(Runnable listener : dependencyListeners)
\r
205 * Sort items to alphabetical order.
\r
207 private void sort() {
\r
208 TableItem[] connectedVariables = variableTable.getItems();
\r
209 Collator collator = Collator.getInstance(Locale.getDefault());
\r
210 for (int i = 1; i < connectedVariables.length; i++) {
\r
211 String value1 = connectedVariables[i].getText(0);
\r
212 for (int j = 0; j < i; j++) {
\r
213 String value2 = connectedVariables[j].getText(0);
\r
214 if (collator.compare(value1, value2) < 0) {
\r
215 String value = connectedVariables[i].getText(0);
\r
216 connectedVariables[i].dispose();
\r
217 TableItem item2 = new TableItem(variableTable, SWT.NONE, j);
\r
218 item2.setText(value);
\r
219 item2.setData(value);
\r
220 connectedVariables = variableTable.getItems();
\r
228 * Get the name of the respective variable.
\r
230 private String getName() {
\r
231 String selfName = null;
\r
233 selfName = SimanticsUI.getSession().syncRequest(new Read<String>() {
\r
235 public String perform(ReadGraph graph)
\r
236 throws DatabaseException {
\r
237 Layer0 l0 = Layer0.getInstance(graph);
\r
238 SysdynResource sr = SysdynResource.getInstance(graph);
\r
240 // Check if we have a stock or some other mystic error.
\r
241 if (!graph.isInstanceOf(variable, sr.Stock)) {
\r
242 Object selfName = graph.getPossibleRelatedValue(variable, l0.HasName);
\r
243 if (selfName instanceof String) {
\r
244 return (String)selfName;
\r
251 catch (DatabaseException e) {
\r
252 e.printStackTrace();
\r
258 public void exception(AsyncReadGraph graph,
\r
259 Throwable throwable) {
\r
260 throwable.printStackTrace();
\r
264 public boolean isDisposed() {
\r
265 return variableTable.isDisposed();
\r
274 public void addFocusListener(FocusListener listener) {
\r
275 this.functionTable.addFocusListener(listener);
\r
276 this.variableTable.addFocusListener(listener);
\r
279 public void addMouseListener(MouseListener listener) {
\r
280 this.functionTable.addMouseListener(listener);
\r
281 this.variableTable.addMouseListener(listener);
\r
284 public void addDependencyListener(Runnable listener) {
\r
285 synchronized(dependencyListeners) {
\r
286 dependencyListeners.add(listener);
\r
290 public void removeDependencyListener(Runnable listener) {
\r
291 synchronized(dependencyListeners) {
\r
292 dependencyListeners.remove(listener);
\r
296 public Table getVariableTable() {
\r
297 return variableTable;
\r