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