1 package org.simantics.selectionview;
3 import java.util.function.Consumer;
5 import org.eclipse.jface.layout.GridDataFactory;
6 import org.eclipse.jface.layout.GridLayoutFactory;
7 import org.eclipse.jface.viewers.ISelection;
8 import org.eclipse.jface.viewers.ISelectionProvider;
9 import org.eclipse.jface.viewers.StructuredSelection;
10 import org.eclipse.swt.SWT;
11 import org.eclipse.swt.widgets.Composite;
12 import org.eclipse.swt.widgets.Control;
13 import org.eclipse.swt.widgets.Event;
14 import org.eclipse.swt.widgets.Listener;
15 import org.eclipse.ui.IWorkbenchSite;
16 import org.simantics.Simantics;
17 import org.simantics.browsing.ui.common.ErrorLogger;
18 import org.simantics.browsing.ui.common.views.IFilterArea;
19 import org.simantics.browsing.ui.common.views.IFilterAreaProvider;
20 import org.simantics.browsing.ui.swt.PartNameListener;
21 import org.simantics.databoard.Bindings;
22 import org.simantics.db.AsyncReadGraph;
23 import org.simantics.db.ReadGraph;
24 import org.simantics.db.Resource;
25 import org.simantics.db.VirtualGraph;
26 import org.simantics.db.WriteGraph;
27 import org.simantics.db.common.procedure.adapter.DisposableAsyncListener;
28 import org.simantics.db.common.procedure.adapter.ListenerSupport;
29 import org.simantics.db.common.request.UniqueRead;
30 import org.simantics.db.common.request.WriteRequest;
31 import org.simantics.db.common.request.WriteResultRequest;
32 import org.simantics.db.common.utils.Logger;
33 import org.simantics.db.common.utils.NameUtils;
34 import org.simantics.db.exception.DatabaseException;
35 import org.simantics.db.exception.ServiceNotFoundException;
36 import org.simantics.db.layer0.variable.Variable;
37 import org.simantics.db.management.ISessionContext;
38 import org.simantics.db.request.Read;
39 import org.simantics.layer0.Layer0;
40 import org.simantics.scenegraph.ontology.ScenegraphResources;
41 import org.simantics.utils.datastructures.Pair;
42 import org.simantics.utils.ui.ISelectionUtils;
43 import org.simantics.utils.ui.jface.ActiveSelectionProvider;
45 abstract public class ModelledTabContributor implements PropertyTabContributor, ListenerSupport {
47 static class InputRead extends UniqueRead<Pair<Variable, Resource>> {
51 InputRead(Object input) {
56 public Pair<Variable, Resource> perform(ReadGraph graph) throws DatabaseException {
58 Variable resultVariable = null;
59 Resource resultResource = null;
61 if(input instanceof ISelection) {
62 Variable var = ISelectionUtils.filterSingleSelection((ISelection)input, Variable.class);
63 if(var != null) resultVariable = var;
64 Resource res = ISelectionUtils.filterSingleSelection((ISelection)input, Resource.class);
65 if(res != null) resultResource = res;
66 } else if (input instanceof Resource) {
67 resultResource = (Resource)input;
70 return Pair.make(resultVariable, resultResource);
76 static class InputListener extends DisposableAsyncListener<Pair<Variable, Resource>> {
78 final Resource runtime;
80 public InputListener(Resource runtime) {
81 this.runtime = runtime;
85 public void execute(AsyncReadGraph graph, final Pair<Variable, Resource> result) {
87 Simantics.getSession().async(new WriteRequest(Simantics.getSession().getService(VirtualGraph.class)) {
90 public void perform(WriteGraph graph) throws DatabaseException {
92 ScenegraphResources SG = ScenegraphResources.getInstance(graph);
94 if(result.first != null) {
95 String uri = result.first.getURI(graph);
96 graph.claimLiteral(runtime, SG.Runtime_HasVariable, uri, Bindings.STRING);
99 if(result.second != null) {
100 graph.deny(runtime, SG.Runtime_HasResource);
101 graph.claim(runtime, SG.Runtime_HasResource, result.second);
111 public void exception(AsyncReadGraph graph, Throwable throwable) {
112 Logger.defaultLogError(throwable);
117 protected Resource runtime;
119 // For ListenerSupport (supporting DB request listeners)
120 protected boolean disposed = false;
121 protected ISelection input = StructuredSelection.EMPTY;
123 protected ISelectionProvider selectionProvider = new ActiveSelectionProvider();
125 abstract public void createControls(Composite body, IWorkbenchSite site);
127 public IFilterArea getFilterArea() {
131 public void requestFocus() {
134 public ISelectionProvider getSelectionProvider() {
135 return selectionProvider;
138 public Read<String> getPartNameReadRequest(final ISelection forSelection) {
139 return new UniqueRead<String>() {
141 private String forResource(ReadGraph graph, Resource resource) throws DatabaseException {
142 Layer0 L0 = Layer0.getInstance(graph);
143 String name = NameUtils.getSafeName(graph, resource);
144 Resource type = graph.getPossibleType(resource, L0.Entity);
146 name += " : " + NameUtils.getSafeName(graph, type);
152 public String perform(ReadGraph graph) throws DatabaseException {
153 Resource resource = ISelectionUtils.filterSingleSelection(forSelection, Resource.class);
154 if(resource != null) return forResource(graph, resource);
155 Variable variable = ISelectionUtils.filterSingleSelection(forSelection, Variable.class);
156 if(variable != null) {
157 Resource represents = variable.getPossibleRepresents(graph);
158 if(represents != null) return forResource(graph, represents);
166 public void updatePartName(ISelection forSelection, Consumer<String> updateCallback) {
167 Read<String> read = getPartNameReadRequest(forSelection);
169 updateCallback.accept("Selection");
171 Simantics.getSession().asyncRequest(read, new PartNameListener(updateCallback, this));
175 public void updatePartName(Consumer<String> updateCallback) {
176 updatePartName(input, updateCallback);
179 protected void dispose() {
180 this.disposed = true;
184 public void exception(Throwable t) {
185 ErrorLogger.defaultLogError("PropertyTabContributorImpl received unexpected exception.", t);
189 public boolean isDisposed() {
193 public Control createControl(Composite parent, final IWorkbenchSite site) {
195 class TabComposite extends Composite {
196 public TabComposite(Composite parent) {
199 GridLayoutFactory.fillDefaults().applyTo(parent);
200 GridDataFactory.fillDefaults().span(1, 1).grab(true, true).applyTo(this);
202 Composite body = this;
203 GridLayoutFactory.fillDefaults().spacing(0, 0).equalWidth(false).numColumns(1).applyTo(body);
206 ModelledTabContributor.this.createControls(body, site);
207 } catch (Throwable t) {
208 ErrorLogger.defaultLogError(t);
213 final TabComposite tc = new TabComposite(parent);
214 tc.addListener(SWT.Dispose, new Listener() {
215 public void handleEvent(Event e) {
216 ModelledTabContributor.this.dispose();
225 public IPropertyTab create(Composite parent, IWorkbenchSite site, ISessionContext context, Object input) {
226 IPropertyTab tab = new Tab(site, parent);
227 tab.createControl((Composite) tab.getControl(), context);
231 class Tab extends Composite implements IPropertyTab2, IFilterAreaProvider {
233 final IWorkbenchSite site;
235 private InputListener listener;
237 public Tab(IWorkbenchSite site, Composite parent) {
239 super(parent, SWT.NONE);
243 runtime = Simantics.getSession().sync(new WriteResultRequest<Resource>(Simantics.getSession().getService(VirtualGraph.class)) {
245 public Resource perform(WriteGraph graph) throws DatabaseException {
246 Layer0 L0 = Layer0.getInstance(graph);
247 ScenegraphResources SG = ScenegraphResources.getInstance(graph);
248 Resource runtime = graph.newResource();
249 graph.claim(runtime, L0.InstanceOf, null, SG.Runtime);
253 } catch (ServiceNotFoundException e) {
254 Logger.defaultLogError(e);
255 } catch (DatabaseException e) {
256 Logger.defaultLogError(e);
262 public void createControl(Composite parent, ISessionContext context) {
263 Control c = ModelledTabContributor.this.createControl(parent, site);
264 c.addListener(SWT.Dispose, new Listener() {
265 public void handleEvent(Event e) {
266 if(listener != null) {
275 public Control getControl() {
280 public boolean isDisposed() {
281 return super.isDisposed();
285 public void requestFocus() {
286 ModelledTabContributor.this.requestFocus();
290 public void setInput(ISessionContext context, ISelection selection, boolean force) {
292 ModelledTabContributor.this.input = selection;
294 if(listener != null) listener.dispose();
296 listener = new InputListener(runtime);
299 Simantics.getSession().syncRequest(new InputRead(ModelledTabContributor.this.input), listener);
300 } catch (DatabaseException e) {
301 Logger.defaultLogError(e);
307 public ISelectionProvider getSelectionProvider() {
308 return ModelledTabContributor.this.getSelectionProvider();
312 public IFilterArea getFilterArea() {
313 return ModelledTabContributor.this.getFilterArea();
317 public void updatePartName(Consumer<String> updateCallback) {
318 ModelledTabContributor.this.updatePartName(input, updateCallback);