X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.document.ui%2Fsrc%2Forg%2Fsimantics%2Fdocument%2Fui%2Fcontribution%2FDocumentTabContribution.java;fp=bundles%2Forg.simantics.document.ui%2Fsrc%2Forg%2Fsimantics%2Fdocument%2Fui%2Fcontribution%2FDocumentTabContribution.java;h=ad1261f82de12a4a8d468fce59a9aec5a668d982;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.document.ui/src/org/simantics/document/ui/contribution/DocumentTabContribution.java b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/contribution/DocumentTabContribution.java new file mode 100644 index 000000000..ad1261f82 --- /dev/null +++ b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/contribution/DocumentTabContribution.java @@ -0,0 +1,337 @@ +package org.simantics.document.ui.contribution; + +import java.util.Collection; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTarget; +import org.eclipse.swt.dnd.DropTargetAdapter; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.Simantics; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.NamedResource; +import org.simantics.db.common.ResourceArray; +import org.simantics.db.common.procedure.adapter.AsyncListenerAdapter; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.request.Read; +import org.simantics.db.service.SerialisationSupport; +import org.simantics.document.DocumentResource; +import org.simantics.document.ui.graphfile.DocumentVersionUtils; +import org.simantics.layer0.Layer0; +import org.simantics.selectionview.AbstractResourceTabContribution; +import org.simantics.selectionview.ComparableTabContributor; +import org.simantics.selectionview.PropertyTabContributorImpl; +import org.simantics.ui.dnd.LocalObjectTransfer; +import org.simantics.ui.dnd.ResourceReferenceTransfer; +import org.simantics.ui.dnd.ResourceTransferUtils; +import org.simantics.ui.utils.ResourceAdaptionUtils; +import org.simantics.ui.workbench.editor.EditorAdapter; +import org.simantics.ui.workbench.editor.EditorRegistry; +import org.simantics.utils.ui.AdaptionUtils; +import org.simantics.utils.ui.ErrorLogger; +import org.simantics.utils.ui.ExceptionUtils; + +/** + * PropertyTab for documents. + * + * + * @author Marko Luukkainen + * + */ +public class DocumentTabContribution extends AbstractResourceTabContribution{ + + + public DocumentTabContribution(ReadGraph graph, Resource r) throws DatabaseException{ + super(graph,r); + } + + @Override + public void getContributors(ReadGraph graph, Resource resource, + Integer priority, String label, + Collection result) + throws DatabaseException { + DocumentResource doc = DocumentResource.getInstance(graph); + if (!graph.isInstanceOf(resource, doc.Document)) + return; + result.add(new ComparableTabContributor(new DocumentPropertyTabContributor(), 1, resource, "Document")); + } + + private class DocumentPropertyTabContributor extends PropertyTabContributorImpl { + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, final WidgetSupport support) { + + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3,3).spacing(1, 1).numColumns(4).applyTo(composite); + + Label label = new Label(composite, SWT.NONE); + label.setText("Name"); + + TrackedText name = new TrackedText(composite, support, SWT.BORDER); + name.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName)); + name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName)); + NameInputValidator validator = new NameInputValidator(); + name.setInputValidator(validator); + support.register(validator); + + Button showButton = new Button(composite, SWT.PUSH); + showButton.setText("Show"); + showButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + openResource(AdaptionUtils.adaptToSingle(support.getInput(),Resource.class)); + } + }); + DocumentResource doc; + try { + doc = DocumentResource.getInstance(context.getSession()); + new DocumentRevisionWidget(composite, support, doc.HasOlderVersion, "Old"); + new DocumentRevisionWidget(composite, support, doc.HasNewerVersion, "New"); + } catch (DatabaseException e1) { + ExceptionUtils.logAndShowError("Cannot create documen version UI", e1); + } + + + GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(name.getWidget()); + GridDataFactory.fillDefaults().span(2, 1).applyTo(showButton); + } + + @Override + public Read getPartNameReadRequest(final ISelection forSelection) { + + return new Read() { + @Override + public String perform(ReadGraph graph) throws DatabaseException { + Resource res = AdaptionUtils.adaptToSingle(forSelection, Resource.class); + if (res == null) + return "N/A"; + Layer0 l0 = Layer0.getInstance(graph); + return graph.getPossibleRelatedValue(res, l0.HasName); + } + }; + } + } + + private static void openResource(final Resource resource) { + Simantics.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + openResource(graph, resource); + } + }); + } + + private static void openResource(ReadGraph graph, final Resource resource) throws DatabaseException{ + EditorAdapter[] adapters = EditorRegistry.getInstance().getAdaptersFor(graph, resource); + if (adapters.length == 0) + return; + EditorAdapter highPri = null; + int pri = Integer.MIN_VALUE; + for (EditorAdapter a : adapters) { + int p = a.getPriority(); + if (highPri == null || p > pri) { + highPri = a; + pri = p; + } + } + final EditorAdapter adapter = highPri; + + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + try { + adapter.openEditor(resource); + } catch (Exception e) { + ExceptionUtils.logAndShowError("Cannot open editor", e); + } + } + }); + } + + private static class DocumentRevisionWidget implements Widget { + ISessionContext context; + + Resource document; + Resource revisionRel; + NamedResource revisionDoc; + + Button showButton; + Button removeButton; + Text text; + + public DocumentRevisionWidget(Composite parent, WidgetSupport support, Resource rel, String name) { + support.register(this); + this.revisionRel = rel; + + Label label = new Label(parent, SWT.NONE); + label.setText(name); + text = new Text(parent, SWT.SINGLE|SWT.BORDER|SWT.READ_ONLY); + showButton = new Button(parent, SWT.PUSH); + showButton.setText("Show"); + showButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (revisionDoc != null) + openResource(revisionDoc.getResource()); + } + }); + removeButton = new Button(parent, SWT.PUSH); + removeButton.setText("Unset"); + removeButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (revisionDoc == null) + return; + try { + context.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + DocumentVersionUtils.unsetVersion(graph, document, revisionDoc.getResource(), revisionRel); + } + }); + revisionDoc = null; + } catch (DatabaseException e1) { + ExceptionUtils.logAndShowError("Cannot remove document revision", e1); + } + updateUI(); + } + }); + + DropTarget dropTarget = new DropTarget(text, DND.DROP_COPY|DND.DROP_LINK); + dropTarget.setTransfer(new Transfer[] { TextTransfer.getInstance(),ResourceReferenceTransfer.getInstance(), LocalObjectTransfer.getTransfer() }); + dropTarget.addDropListener(new DropTargetAdapter() { + + @Override + public void dragEnter(DropTargetEvent event) { + // drop data is null, so we cannot to validate drop. + event.detail = DND.DROP_LINK; + } + + @Override + public void drop(DropTargetEvent event) { + ResourceArray[] data = parseEventData(event); + if (data.length != 1) + return; + if (data[0].resources ==null || data[0].resources.length != 1) + return; + setRevisionDoc(data[0].resources[0]); + } + + private ResourceArray[] parseEventData(DropTargetEvent event) { + if (event.data instanceof String) { + try { + SerialisationSupport support = context.getSession().getService(SerialisationSupport.class); + return ResourceTransferUtils.readStringTransferable(support, (String) event.data).toResourceArrayArray(); + } catch (IllegalArgumentException e) { + ErrorLogger.defaultLogError(e); + } catch (DatabaseException e) { + ErrorLogger.defaultLogError(e); + } + } + ResourceArray[] ret = ResourceAdaptionUtils.toResourceArrays(event.data); + if (ret.length > 0) + return ret; + return null; + } + }); + + GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(text); + + } + + @Override + public void setInput(ISessionContext context, Object input) { + this.context = context; + document = AdaptionUtils.adaptToSingle(input, Resource.class); + + context.getSession().asyncRequest(new Read() { + @Override + public NamedResource perform(ReadGraph graph) + throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + Resource revisionDoc = graph.getPossibleObject(document, revisionRel); + if (revisionDoc == null) + return null; + return new NamedResource((String)graph.getRelatedValue(revisionDoc, l0.HasName), revisionDoc); + } + },new AsyncListenerAdapter(){ + @Override + public void execute(AsyncReadGraph graph,final NamedResource result) { + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + revisionDoc = result; + updateUI(); + } + }); + } + + @Override + public void exception(AsyncReadGraph graph, Throwable t) { + ExceptionUtils.logAndShowError("Cannot show document revision", t); + } + + @Override + public boolean isDisposed() { + return showButton.isDisposed(); + } + }); + + + updateUI(); + } + + private void updateUI() { + if (showButton.isDisposed()) + return; + showButton.setEnabled(revisionDoc != null); + removeButton.setEnabled(revisionDoc != null); + if (revisionDoc != null) + text.setText(revisionDoc.getName()); + else + text.setText(""); + } + + private void setRevisionDoc(final Resource toSet) { + context.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + DocumentVersionUtils.setVersion(graph, document, toSet, revisionRel); + } + }); + } + + } + + +}