X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.selectionview%2Fsrc%2Forg%2Fsimantics%2Fselectionview%2FModelledTabContributor.java;fp=bundles%2Forg.simantics.selectionview%2Fsrc%2Forg%2Fsimantics%2Fselectionview%2FModelledTabContributor.java;h=983e52801b784069ca35c743b51c72276ca42bab;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.selectionview/src/org/simantics/selectionview/ModelledTabContributor.java b/bundles/org.simantics.selectionview/src/org/simantics/selectionview/ModelledTabContributor.java new file mode 100644 index 000000000..983e52801 --- /dev/null +++ b/bundles/org.simantics.selectionview/src/org/simantics/selectionview/ModelledTabContributor.java @@ -0,0 +1,323 @@ +package org.simantics.selectionview; + +import java.util.function.Consumer; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.Simantics; +import org.simantics.browsing.ui.common.ErrorLogger; +import org.simantics.browsing.ui.common.views.IFilterArea; +import org.simantics.browsing.ui.common.views.IFilterAreaProvider; +import org.simantics.browsing.ui.swt.PartNameListener; +import org.simantics.databoard.Bindings; +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.VirtualGraph; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.procedure.adapter.DisposableAsyncListener; +import org.simantics.db.common.procedure.adapter.ListenerSupport; +import org.simantics.db.common.request.UniqueRead; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.request.WriteResultRequest; +import org.simantics.db.common.utils.Logger; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ServiceNotFoundException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.scenegraph.ontology.ScenegraphResources; +import org.simantics.utils.datastructures.Pair; +import org.simantics.utils.ui.ISelectionUtils; +import org.simantics.utils.ui.jface.ActiveSelectionProvider; + +abstract public class ModelledTabContributor implements PropertyTabContributor, ListenerSupport { + + static class InputRead extends UniqueRead> { + + private Object input; + + InputRead(Object input) { + this.input = input; + } + + @Override + public Pair perform(ReadGraph graph) throws DatabaseException { + + Variable resultVariable = null; + Resource resultResource = null; + + if(input instanceof ISelection) { + Variable var = ISelectionUtils.filterSingleSelection((ISelection)input, Variable.class); + if(var != null) resultVariable = var; + Resource res = ISelectionUtils.filterSingleSelection((ISelection)input, Resource.class); + if(res != null) resultResource = res; + } else if (input instanceof Resource) { + resultResource = (Resource)input; + } + + return Pair.make(resultVariable, resultResource); + + } + + }; + + static class InputListener extends DisposableAsyncListener> { + + final Resource runtime; + + public InputListener(Resource runtime) { + this.runtime = runtime; + } + + @Override + public void execute(AsyncReadGraph graph, final Pair result) { + + Simantics.getSession().async(new WriteRequest(Simantics.getSession().getService(VirtualGraph.class)) { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + + ScenegraphResources SG = ScenegraphResources.getInstance(graph); + + if(result.first != null) { + String uri = result.first.getURI(graph); + graph.claimLiteral(runtime, SG.Runtime_HasVariable, uri, Bindings.STRING); + } + + if(result.second != null) { + graph.deny(runtime, SG.Runtime_HasResource); + graph.claim(runtime, SG.Runtime_HasResource, result.second); + } + + } + + }); + + } + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + Logger.defaultLogError(throwable); + } + + } + + protected Resource runtime; + + // For ListenerSupport (supporting DB request listeners) + protected boolean disposed = false; + protected ISelection input = StructuredSelection.EMPTY; + + protected ISelectionProvider selectionProvider = new ActiveSelectionProvider(); + + abstract public void createControls(Composite body, IWorkbenchSite site); + + public IFilterArea getFilterArea() { + return null; + } + + public void requestFocus() { + } + + public ISelectionProvider getSelectionProvider() { + return selectionProvider; + } + + public Read getPartNameReadRequest(final ISelection forSelection) { + return new UniqueRead() { + + private String forResource(ReadGraph graph, Resource resource) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + String name = NameUtils.getSafeName(graph, resource); + Resource type = graph.getPossibleType(resource, L0.Entity); + if(type != null) { + name += " : " + NameUtils.getSafeName(graph, type); + } + return name; + } + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + Resource resource = ISelectionUtils.filterSingleSelection(forSelection, Resource.class); + if(resource != null) return forResource(graph, resource); + Variable variable = ISelectionUtils.filterSingleSelection(forSelection, Variable.class); + if(variable != null) { + Resource represents = variable.getPossibleRepresents(graph); + if(represents != null) return forResource(graph, represents); + } + return "Selection"; + } + + }; + } + + public void updatePartName(ISelection forSelection, Consumer updateCallback) { + Read read = getPartNameReadRequest(forSelection); + if (read == null) { + updateCallback.accept("Selection"); + } else { + Simantics.getSession().asyncRequest(read, new PartNameListener(updateCallback, this)); + } + } + + public void updatePartName(Consumer updateCallback) { + updatePartName(input, updateCallback); + } + + protected void dispose() { + this.disposed = true; + } + + @Override + public void exception(Throwable t) { + ErrorLogger.defaultLogError("PropertyTabContributorImpl received unexpected exception.", t); + } + + @Override + public boolean isDisposed() { + return disposed; + } + + public Control createControl(Composite parent, final IWorkbenchSite site) { + + class TabComposite extends Composite { + public TabComposite(Composite parent) { + super(parent, 0); + + GridLayoutFactory.fillDefaults().applyTo(parent); + GridDataFactory.fillDefaults().span(1, 1).grab(true, true).applyTo(this); + + Composite body = this; + GridLayoutFactory.fillDefaults().spacing(0, 0).equalWidth(false).numColumns(1).applyTo(body); + + try { + ModelledTabContributor.this.createControls(body, site); + } catch (Throwable t) { + ErrorLogger.defaultLogError(t); + } + } + } + + final TabComposite tc = new TabComposite(parent); + tc.addListener(SWT.Dispose, new Listener() { + public void handleEvent(Event e) { + ModelledTabContributor.this.dispose(); + } + }); + + return tc; + + } + + @Override + public IPropertyTab create(Composite parent, IWorkbenchSite site, ISessionContext context, Object input) { + IPropertyTab tab = new Tab(site, parent); + tab.createControl((Composite) tab.getControl(), context); + return tab; + } + + class Tab extends Composite implements IPropertyTab2, IFilterAreaProvider { + + final IWorkbenchSite site; + + private InputListener listener; + + public Tab(IWorkbenchSite site, Composite parent) { + + super(parent, SWT.NONE); + this.site = site; + + try { + runtime = Simantics.getSession().sync(new WriteResultRequest(Simantics.getSession().getService(VirtualGraph.class)) { + @Override + public Resource perform(WriteGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + ScenegraphResources SG = ScenegraphResources.getInstance(graph); + Resource runtime = graph.newResource(); + graph.claim(runtime, L0.InstanceOf, null, SG.Runtime); + return runtime; + } + }); + } catch (ServiceNotFoundException e) { + Logger.defaultLogError(e); + } catch (DatabaseException e) { + Logger.defaultLogError(e); + } + + } + + @Override + public void createControl(Composite parent, ISessionContext context) { + Control c = ModelledTabContributor.this.createControl(parent, site); + c.addListener(SWT.Dispose, new Listener() { + public void handleEvent(Event e) { + if(listener != null) { + listener.dispose(); + listener = null; + } + } + }); + } + + @Override + public Control getControl() { + return this; + } + + @Override + public boolean isDisposed() { + return super.isDisposed(); + } + + @Override + public void requestFocus() { + ModelledTabContributor.this.requestFocus(); + } + + @Override + public void setInput(ISessionContext context, ISelection selection, boolean force) { + + ModelledTabContributor.this.input = selection; + + if(listener != null) listener.dispose(); + + listener = new InputListener(runtime); + + try { + Simantics.getSession().syncRequest(new InputRead(ModelledTabContributor.this.input), listener); + } catch (DatabaseException e) { + Logger.defaultLogError(e); + } + + } + + @Override + public ISelectionProvider getSelectionProvider() { + return ModelledTabContributor.this.getSelectionProvider(); + } + + @Override + public IFilterArea getFilterArea() { + return ModelledTabContributor.this.getFilterArea(); + } + + @Override + public void updatePartName(Consumer updateCallback) { + ModelledTabContributor.this.updatePartName(input, updateCallback); + } + + } + +}