--- /dev/null
+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