]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.document.linking.ui/src/org/simantics/document/linking/views/SourceView.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.document.linking.ui / src / org / simantics / document / linking / views / SourceView.java
diff --git a/bundles/org.simantics.document.linking.ui/src/org/simantics/document/linking/views/SourceView.java b/bundles/org.simantics.document.linking.ui/src/org/simantics/document/linking/views/SourceView.java
new file mode 100644 (file)
index 0000000..68c2b00
--- /dev/null
@@ -0,0 +1,473 @@
+package org.simantics.document.linking.views;
+
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Sash;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.part.ViewPart;
+import org.simantics.Simantics;
+import org.simantics.browsing.ui.GraphExplorer;
+import org.simantics.browsing.ui.swt.SingleSelectionInputSource;
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.exception.AdaptionException;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.request.Read;
+import org.simantics.document.DocumentResource;
+import org.simantics.document.linking.Activator;
+import org.simantics.document.linking.adapters.SourceObjectAdapter;
+import org.simantics.document.linking.ge.Constants;
+import org.simantics.document.linking.ge.MultiSelectionProvider;
+import org.simantics.document.linking.ge.SourceLinkExplorerComposite;
+import org.simantics.document.linking.ontology.DocumentLink;
+import org.simantics.ui.SimanticsUI;
+import org.simantics.utils.datastructures.ArrayMap;
+import org.simantics.utils.ui.AdaptionUtils;
+
+
+public class SourceView extends ViewPart implements ISelectionListener, IPartListener{
+
+       
+       public enum AcceptedObject{ALL,DOCUMENT};
+       /**
+        * The ID of the view as specified by the extension.
+        */
+       public static final String ID = "org.simantics.document.linking.views.SourceView";
+
+       private Composite composite;
+
+       private Action pinSelectionAction;
+       private Action linkAllAction;
+       private Action linkDocumentsAction;
+
+       private WidgetSupport support;
+       private GraphExplorerComposite objectExplorer;
+       private GraphExplorerComposite propertyExplorer;
+       private MultiSelectionProvider selectionProvider;
+       
+       private GraphExplorerComposite browseExplorer;
+       
+       
+       private TabFolder tabFolder;
+       
+       Composite linkComposite;
+       Composite browseComposite;
+       
+       private boolean pinSelection = false;
+       
+       Resource currentModel;
+       private ModelToComboListener modelToComboListener;
+       private CCombo modelCombo;
+
+       private AcceptedObject acceptedObject = AcceptedObject.DOCUMENT;
+       /**
+        * The constructor.
+        */
+       public SourceView() {
+               support = new WidgetSupportImpl();
+       }
+
+       /**
+        * This is a callback that will allow us
+        * to create the viewer and initialize it.
+        */
+       public void createPartControl(Composite parent) {
+                parent.setLayout(new FillLayout());
+               composite = new Composite(parent, SWT.NONE);
+               composite.setLayout(new FillLayout());
+               tabFolder = new TabFolder(composite, SWT.NONE);
+               TabItem link = new TabItem(tabFolder, SWT.NONE);
+               link.setText("Linking");
+               
+               TabItem browse = new TabItem(tabFolder, SWT.NONE);
+               browse.setText("Browsing");
+               
+               linkComposite = new Composite(tabFolder, SWT.NONE);
+               link.setControl(linkComposite);
+               
+               browseComposite = new Composite(tabFolder, SWT.NONE);
+               browse.setControl(browseComposite);
+               
+               selectionProvider = new MultiSelectionProvider();
+               
+               createLinkTab(linkComposite);
+        createBrowseTab(browseComposite);
+        
+        getSite().getPage().addPostSelectionListener(this);
+        getSite().getPage().addPartListener(this);
+               makeActions();
+
+               contributeToActionBars();
+               
+               getSite().setSelectionProvider(selectionProvider);
+               
+               
+       }
+       
+       @Override
+       public void dispose() {
+                getSite().getPage().removePostSelectionListener(this);
+            getSite().getPage().removePartListener(this);
+       }
+       
+       private void createBrowseTab(final Composite browseComposite) {
+               browseComposite.setLayout(new GridLayout(2,false));
+               modelCombo = new CCombo(browseComposite, SWT.BORDER|SWT.READ_ONLY);
+               final WidgetSupport support = new WidgetSupportImpl();
+               SimanticsUI.getSession().asyncRequest(new ReadRequest() {
+                       
+                       @Override
+                       public void run(ReadGraph graph) throws DatabaseException {
+                               Resource project = SimanticsUI.getProject().get();
+                               modelToComboListener = new ModelToComboListener(modelCombo) {
+                                       @Override
+                                       public Resource getCurrentModel() {
+                                               return currentModel;
+                                       }
+                               };
+                               graph.syncRequest(new ModelRead(project),modelToComboListener);
+                               
+                       }
+               });
+               Button checkingButton = new Button(browseComposite, SWT.TOGGLE);
+               checkingButton.setText("All");
+               checkingButton.addSelectionListener(new SelectionAdapter() {
+                       @Override
+                       public void widgetSelected(SelectionEvent e) {
+                               Button button = ((Button)e.widget);
+                               boolean checked = button.getSelection();
+                               browseExplorer.dispose();
+                               createModelExplorer(checked,support,browseComposite);
+                               button.setText(checked ? "Old/Removed" : "All");
+                               if (currentModel != null)
+                                       setModel(currentModel, true);
+                               browseComposite.getParent().layout(true, true);
+                       }
+               });
+               
+               createModelExplorer(false,support,browseComposite);
+               
+        
+        modelCombo.addSelectionListener(new SelectionAdapter() {
+                       @Override
+                       public void widgetSelected(SelectionEvent e) {
+                               int index = modelCombo.getSelectionIndex();
+                               if (index == -1)
+                                       return;
+                               Resource model = (Resource)modelCombo.getData(Integer.toString(index));
+                               if (model != null)
+                                       setModel(model);
+                       }
+               });
+        
+        GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).grab(true, false).applyTo(modelCombo);
+       
+       }
+       
+       private void createModelExplorer(boolean onlyCheckable,WidgetSupport support,Composite browseComposite) {
+               browseExplorer = new SourceLinkExplorerComposite(ArrayMap.keys("displaySelectors", "displayFilter","treeView").values(false, false, true), selectionProvider,getSite(), browseComposite, support,false, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
+               if(!onlyCheckable)
+                       browseExplorer.setBrowseContexts(DocumentLink.URIs.ModelViewpointBrowseContext, DocumentLink.URIs.ModelViewpointActionContext);
+               else
+                       browseExplorer.setBrowseContexts(DocumentLink.URIs.ModelViewpointBrowseContext2, DocumentLink.URIs.ModelViewpointActionContext);
+               browseExplorer.setColumns(Constants.SOURCE_OBJECT_COLUMNS);
+               browseExplorer.setInputSource(new SingleSelectionInputSource(Resource.class));
+               browseExplorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning
+               browseExplorer.setColumnsVisible(true);
+               browseExplorer.setContextMenuId("#SourceModelViewPopup");
+               browseExplorer.finish();
+        ((Tree)browseExplorer.getExplorer().getControl()).setLinesVisible(true);
+        
+        GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).span(2, 1).applyTo(browseExplorer);
+       }
+       
+       private void createLinkTab(final Composite linkComposite) {
+               objectExplorer = new SourceLinkExplorerComposite(ArrayMap.keys("displaySelectors", "displayFilter","treeView").values(false, false,true), selectionProvider,getSite(), linkComposite, support, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
+               objectExplorer.setBrowseContexts(DocumentLink.URIs.SourceObjectViewpointBrowseContext, DocumentLink.URIs.SourceObjectViewpointActionContext);
+               objectExplorer.setColumns(Constants.SOURCE_OBJECT_COLUMNS);
+               objectExplorer.setInputSource(new SingleSelectionInputSource(Resource.class));
+               objectExplorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning
+               objectExplorer.setColumnsVisible(true);
+               objectExplorer.setContextMenuId("#SourceObjectViewPopup");
+               objectExplorer.finish();
+        ((Tree)objectExplorer.getExplorer().getControl()).setLinesVisible(true);
+        
+        final Sash sash = new Sash (linkComposite, SWT.HORIZONTAL);
+        
+               propertyExplorer = new SourceLinkExplorerComposite(ArrayMap.keys("displaySelectors", "displayFilter","treeView").values(false, false,true), selectionProvider,getSite(), linkComposite, support, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
+               propertyExplorer.setBrowseContexts(DocumentLink.URIs.SourcePropertyViewpointBrowseContext, DocumentLink.URIs.SourcePropertyViewpointActionContext);
+               propertyExplorer.setColumns(Constants.SOURCE_COLUMNS);
+               propertyExplorer.setInputSource(new SingleSelectionInputSource(Resource.class));
+               propertyExplorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning
+               propertyExplorer.setColumnsVisible(true);
+               propertyExplorer.setContextMenuId("#SourcePropertyViewPopup");
+        propertyExplorer.finish();
+        ((Tree)propertyExplorer.getExplorer().getControl()).setLinesVisible(true);
+        
+       
+        final FormLayout form = new FormLayout ();
+        linkComposite.setLayout (form);
+        
+        FormData button1Data = new FormData ();
+       button1Data.left = new FormAttachment (0, 0);
+       button1Data.right = new FormAttachment (100, 0);
+       button1Data.top = new FormAttachment (0, 0);
+       button1Data.bottom = new FormAttachment (sash, 0);
+       objectExplorer.setLayoutData (button1Data);
+
+       final int limit = 40, percent = 20;
+       final FormData sashData = new FormData ();
+       sashData.left = new FormAttachment (0, 0);
+       sashData.right = new FormAttachment (100, 0);
+       sashData.top = new FormAttachment (percent, 0);
+       
+       sash.setLayoutData (sashData);
+       sash.addListener (SWT.Selection, new Listener () {
+               public void handleEvent (Event e) {
+                       Rectangle sashRect = sash.getBounds ();
+                       Rectangle shellRect = linkComposite.getClientArea ();
+                       int top = shellRect.height - sashRect.height - limit;
+                       e.y = Math.max (Math.min (e.y, top), limit);
+                       if (e.y != sashRect.y)  {
+                               sashData.top = new FormAttachment (0, e.y);
+                               linkComposite.layout ();
+                       }
+               }
+       });
+       
+       FormData button2Data = new FormData ();
+       button2Data.left = new FormAttachment (0, 0);
+       button2Data.right = new FormAttachment (100, 0);
+       button2Data.top = new FormAttachment (sash, 0);
+       button2Data.bottom = new FormAttachment (100, 0);
+       propertyExplorer.setLayoutData (button2Data);
+       }
+       
+
+       
+       @Override
+       public void partActivated(IWorkbenchPart part) {
+               if (!(part instanceof IEditorPart))
+                       selectionEventFilter = part;
+       }
+       
+       @Override
+       public void partBroughtToTop(IWorkbenchPart part) {}
+       
+       @Override
+       public void partClosed(IWorkbenchPart part) {}
+       
+       @Override
+       public void partDeactivated(IWorkbenchPart part) {}
+       
+       @Override
+       public void partOpened(IWorkbenchPart part) {}
+       
+       IWorkbenchPart selectionEventFilter = null;
+       
+       @Override
+       public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+               if (part == this)
+                       return;
+               if (pinSelection)
+                       return;
+               // dnd event may start from different part than the target object is selected.
+               // activating an part sends not only partActivated event, but also selectioChanged event to match the part's selection
+               // since that would interrupt intended dnd operation, we filter selection events send by part activation.
+               if (part == selectionEventFilter) {
+                       selectionEventFilter = null;
+                       return;
+               }
+               selectionEventFilter = null;
+               
+               final Resource res = AdaptionUtils.adaptToSingle(selection, Resource.class);
+               if (res == null)
+                       return;
+               try {
+                       final Resource selected  = SimanticsUI.getSession().syncRequest(new Read<Resource>() {
+                               @Override
+                               public Resource perform(ReadGraph graph) throws DatabaseException {
+                                       try {
+                                               SourceObjectAdapter adapter = graph.adapt(res, SourceObjectAdapter.class);
+                                               return adapter.getDocumentableResource(graph, res);
+                                       } catch (AdaptionException e) {
+                                               return res;
+                                       }
+                               }
+                       });
+                       if (selected == null)
+                               return;
+                       if (acceptedObject == AcceptedObject.DOCUMENT) {
+                               if (Simantics.getSession().syncRequest(new IsDocumentRead(selected)))
+                                       return;
+                       }
+                       ISelection realSelection = new StructuredSelection(selected);
+                       objectExplorer.setInput(SimanticsUI.getSessionContext(), realSelection);
+                       propertyExplorer.setInput(SimanticsUI.getSessionContext(), realSelection);
+                       Simantics.getSession().asyncRequest(new ReadRequest() {
+                               
+                               @Override
+                               public void run(ReadGraph graph) throws DatabaseException {
+                                       String name = NameUtils.getSafeLabel(graph, selected);
+                                       if (name.length() == 0)
+                                               name = NameUtils.getSafeName(graph, selected);
+                                       final String title = name;
+                                       Display.getDefault().asyncExec(new Runnable() {
+                                               @Override
+                                               public void run() {
+                                                       setPartName(title);
+                                                       
+                                               }
+                                       }) ;
+                               }
+                       });
+               } catch (Exception e) {
+                       
+               }
+       }
+       
+       private class IsDocumentRead extends ResourceRead<Boolean> {
+               public IsDocumentRead(Resource resource) {
+                       super(resource);
+               }
+
+               @Override
+               public Boolean perform(ReadGraph graph) throws DatabaseException {
+                       DocumentResource doc = DocumentResource.getInstance(graph);
+                       return graph.isInstanceOf(resource, doc.Document);
+               }
+       }
+
+
+       private void contributeToActionBars() {
+               IActionBars bars = getViewSite().getActionBars();
+               fillLocalPullDown(bars.getMenuManager());
+               fillLocalToolBar(bars.getToolBarManager());
+       }
+
+       private void fillLocalPullDown(IMenuManager manager) {
+               manager.add(linkAllAction);
+               manager.add(linkDocumentsAction);
+       }
+
+       
+       private void fillLocalToolBar(IToolBarManager manager) {
+               manager.add(pinSelectionAction);
+
+       }
+
+       private void makeActions() {
+               pinSelectionAction = new Action("Pin selection", Action.AS_CHECK_BOX) {
+                       public void run() {
+                               pinSelection = isChecked();
+                       }
+               };
+//             action1.setToolTipText("Action 1 tooltip");
+               pinSelectionAction.setImageDescriptor(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/lock.png"));
+               
+               
+               linkAllAction = new Action("Link All", Action.AS_RADIO_BUTTON) {
+                       @Override
+                       public void run() {
+                               setAcceptedObject(AcceptedObject.ALL);
+                               
+                       }
+               };
+               
+               linkDocumentsAction = new Action("Link Documents", Action.AS_RADIO_BUTTON) {
+                       @Override
+                       public void run() {
+                               setAcceptedObject(AcceptedObject.DOCUMENT);
+
+                       }
+               };
+               setAcceptedObject(AcceptedObject.DOCUMENT);
+
+       }
+       
+       public void setAcceptedObject(AcceptedObject acceptedObject) {
+               this.acceptedObject = acceptedObject;
+               if (acceptedObject == AcceptedObject.ALL) {
+                       linkAllAction.setChecked(true);
+                       linkDocumentsAction.setChecked(false);
+               } else {
+                       linkAllAction.setChecked(false);
+                       linkDocumentsAction.setChecked(true);
+               }
+       }
+
+
+
+
+       /**
+        * Passing the focus request to the viewer's control.
+        */
+       public void setFocus() {
+               composite.setFocus();
+       }
+       
+       public void setModel(Resource model) {
+               setModel(model, false);
+       }
+       
+       public void setModel(Resource model, boolean force) {
+               if (!force && model.equals(currentModel))
+                       return;
+               
+               currentModel = model;
+               for (int i = 0; i < modelCombo.getItemCount(); i++) {
+                       Resource r = (Resource)modelCombo.getData(Integer.toString(i));
+                       if (model.equals(r)) {
+                               modelCombo.select(i);
+                               ISelection realSelection = new StructuredSelection(currentModel);
+                               browseExplorer.setInput(SimanticsUI.getSessionContext(), realSelection);
+                               return;
+                       }
+               }
+               modelCombo.select(-1);
+               ISelection realSelection = new StructuredSelection();
+               browseExplorer.setInput(SimanticsUI.getSessionContext(), realSelection);
+       }
+       
+       @SuppressWarnings("rawtypes")
+       @Override
+       public Object getAdapter(Class adapter) {
+               if (adapter == GraphExplorer.class) {
+                       return browseExplorer.getExplorer();
+               }
+               return super.getAdapter(adapter);
+       }
+}
\ No newline at end of file